Repository: d365collaborative/d365fo.tools Branch: master Commit: 20562ddf3d4c Files: 915 Total size: 4.4 MB Directory structure: gitextract_ur7j2o7_/ ├── .gitattributes ├── .github/ │ └── workflows/ │ ├── Release-Management.yml │ ├── build-manual.yml │ ├── build.yml │ ├── dependencies.yml │ ├── update-generated-text.yml │ └── update-wiki.yml ├── .gitignore ├── LICENSE ├── README.md ├── build/ │ ├── buildtools.ps1 │ ├── filesAfter.txt │ ├── filesBefore.txt │ ├── format-commentbasedhelp.ps1 │ ├── generate-findcommandindex.ps1 │ ├── generate-parameterunittests.ps1 │ ├── update-docs.ps1 │ ├── vsts-build.ps1 │ ├── vsts-prerequisites.ps1 │ ├── vsts-validate-psscriptanalyzer.ps1 │ └── vsts-validate.ps1 ├── contributing.md ├── d365fo.tools/ │ ├── bin/ │ │ ├── d365fo.tools-index.json │ │ └── readme.md │ ├── d365fo.tools.psd1 │ ├── d365fo.tools.psm1 │ ├── en-us/ │ │ ├── about_Deployable_Packages.help.txt │ │ └── about_d365fo.tools.help.txt │ ├── functions/ │ │ ├── add-d365azurestorageconfig.ps1 │ │ ├── add-d365broadcastmessageconfig.ps1 │ │ ├── add-d365moduletoremove.ps1 │ │ ├── add-d365rsatwifconfigauthoritythumbprint.ps1 │ │ ├── add-d365windowsdefenderrules.ps1 │ │ ├── backup-d365devconfig.ps1 │ │ ├── backup-d365metadatadir.ps1 │ │ ├── backup-d365runbook.ps1 │ │ ├── backup-d365webconfig.ps1 │ │ ├── backup-d365wifconfig.ps1 │ │ ├── clear-d365activebroadcastmessageconfig.ps1 │ │ ├── clear-d365bacpacobject.ps1 │ │ ├── clear-d365bacpactabledata.ps1 │ │ ├── clear-d365monitordata.ps1 │ │ ├── clear-d365tempdbtables.ps1 │ │ ├── convertto-d365dacpac.ps1 │ │ ├── disable-d365exception.ps1 │ │ ├── disable-d365flight.ps1 │ │ ├── disable-d365iispreload.ps1 │ │ ├── disable-d365maintenancemode.ps1 │ │ ├── disable-d365sqlchangetracking.ps1 │ │ ├── disable-d365user.ps1 │ │ ├── enable-d365exception.ps1 │ │ ├── enable-d365flight.ps1 │ │ ├── enable-d365iispreload.ps1 │ │ ├── enable-d365maintenancemode.ps1 │ │ ├── enable-d365sqlchangetracking.ps1 │ │ ├── enable-d365user.ps1 │ │ ├── export-d365bacpacmodelfile.ps1 │ │ ├── export-d365model.ps1 │ │ ├── export-d365securitydetails.ps1 │ │ ├── find-d365command.ps1 │ │ ├── get-d365activeazurestorageconfig.ps1 │ │ ├── get-d365activebroadcastmessageconfig.ps1 │ │ ├── get-d365aotobject.ps1 │ │ ├── get-d365azuredevopsnuget.ps1 │ │ ├── get-d365azurestorageconfig.ps1 │ │ ├── get-d365azurestoragefile.ps1 │ │ ├── get-d365azurestorageurl.ps1 │ │ ├── get-d365bacpacsqloptions.ps1 │ │ ├── get-d365bacpactable.ps1 │ │ ├── get-d365broadcastmessage.ps1 │ │ ├── get-d365broadcastmessageconfig.ps1 │ │ ├── get-d365clickoncetrustprompt.ps1 │ │ ├── get-d365compilerresult.ps1 │ │ ├── get-d365database.ps1 │ │ ├── get-d365databaseaccess.ps1 │ │ ├── get-d365decryptedwebconfig.ps1 │ │ ├── get-d365defaultmodelfornewprojects.ps1 │ │ ├── get-d365dotnetclass.ps1 │ │ ├── get-d365dotnetmethod.ps1 │ │ ├── get-d365environment.ps1 │ │ ├── get-d365environmentsettings.ps1 │ │ ├── get-d365eventtraceprovider.ps1 │ │ ├── get-d365externalip.ps1 │ │ ├── get-d365flight.ps1 │ │ ├── get-d365iispreload.ps1 │ │ ├── get-d365installedhotfix.ps1 │ │ ├── get-d365installedpackage.ps1 │ │ ├── get-d365installedservice.ps1 │ │ ├── get-d365instancename.ps1 │ │ ├── get-d365jsonservice.ps1 │ │ ├── get-d365label.ps1 │ │ ├── get-d365labelfile.ps1 │ │ ├── get-d365language.ps1 │ │ ├── get-d365lcsapiconfig.ps1 │ │ ├── get-d365lcsapitoken.ps1 │ │ ├── get-d365lcsassetfile.ps1 │ │ ├── get-d365lcsassetvalidationstatus.ps1 │ │ ├── get-d365lcsdatabasebackups.ps1 │ │ ├── get-d365lcsdatabaseoperationstatus.ps1 │ │ ├── get-d365lcsdeploymentstatus.ps1 │ │ ├── get-d365lcsenvironmenthistory.ps1 │ │ ├── get-d365lcsenvironmentmetadata.ps1 │ │ ├── get-d365lcsenvironmentrsatcertificate.ps1 │ │ ├── get-d365lcssharedassetfile.ps1 │ │ ├── get-d365maintenancemode.ps1 │ │ ├── get-d365model.ps1 │ │ ├── get-d365module.ps1 │ │ ├── get-d365offlineauthenticationadminemail.ps1 │ │ ├── get-d365packagebundledetail.ps1 │ │ ├── get-d365packagelabelresourcefile.ps1 │ │ ├── get-d365packagelabelresources.ps1 │ │ ├── get-d365productinformation.ps1 │ │ ├── get-d365rsatcertificatethumbprint.ps1 │ │ ├── get-d365rsatplaybackfile.ps1 │ │ ├── get-d365rsatsoaphostname.ps1 │ │ ├── get-d365runbook.ps1 │ │ ├── get-d365runbookid.ps1 │ │ ├── get-d365runbooklogfile.ps1 │ │ ├── get-d365sdpcleanup.ps1 │ │ ├── get-d365sdpdetails.ps1 │ │ ├── get-d365table.ps1 │ │ ├── get-d365tablefield.ps1 │ │ ├── get-d365tablesequence.ps1 │ │ ├── get-d365tablesinchangedtracking.ps1 │ │ ├── get-d365tfsuri.ps1 │ │ ├── get-d365tfsworkspace.ps1 │ │ ├── get-d365url.ps1 │ │ ├── get-d365user.ps1 │ │ ├── get-d365userauthenticationdetail.ps1 │ │ ├── get-d365visualstudiocompilerresult.ps1 │ │ ├── get-d365webservertype.ps1 │ │ ├── get-d365windowsactivationstatus.ps1 │ │ ├── import-d365aadapplication.ps1 │ │ ├── import-d365aaduser.ps1 │ │ ├── import-d365bacpac.ps1 │ │ ├── import-d365dacpac.ps1 │ │ ├── import-d365externaluser.ps1 │ │ ├── import-d365model.ps1 │ │ ├── import-d365rsatselfservicecertificates.ps1 │ │ ├── initialize-d365rsatcertificate.ps1 │ │ ├── install-d365supportingsoftware.ps1 │ │ ├── invoke-d365azcopytransfer.ps1 │ │ ├── invoke-d365azuredevopsnugetpush.ps1 │ │ ├── invoke-d365azurestoragedownload.ps1 │ │ ├── invoke-d365azurestorageupload.ps1 │ │ ├── invoke-d365bestpractice.ps1 │ │ ├── invoke-d365compilerresultanalyzer.ps1 │ │ ├── invoke-d365dataflush.ps1 │ │ ├── invoke-d365dbsync.ps1 │ │ ├── invoke-d365dbsyncmodule.ps1 │ │ ├── invoke-d365dbsyncpartial.ps1 │ │ ├── invoke-d365generatereportaggregatedataentity.ps1 │ │ ├── invoke-d365generatereportaggregatemeasure.ps1 │ │ ├── invoke-d365generatereportconfigkey.ps1 │ │ ├── invoke-d365generatereportconfigkeygroup.ps1 │ │ ├── invoke-d365generatereportdataentity.ps1 │ │ ├── invoke-d365generatereportdataentityfield.ps1 │ │ ├── invoke-d365generatereportkpi.ps1 │ │ ├── invoke-d365generatereportlicensecode.ps1 │ │ ├── invoke-d365generatereportmenuitem.ps1 │ │ ├── invoke-d365generatereports.ps1 │ │ ├── invoke-d365generatereportssrs.ps1 │ │ ├── invoke-d365generatereporttable.ps1 │ │ ├── invoke-d365generatereportworkflowtype.ps1 │ │ ├── invoke-d365installazcopy.ps1 │ │ ├── invoke-d365installlicense.ps1 │ │ ├── invoke-d365installnuget.ps1 │ │ ├── invoke-d365installsqlpackage.ps1 │ │ ├── invoke-d365lcsapirefreshtoken.ps1 │ │ ├── invoke-d365lcsdatabaseexport.ps1 │ │ ├── invoke-d365lcsdatabaserefresh.ps1 │ │ ├── invoke-d365lcsdeployment.ps1 │ │ ├── invoke-d365lcsenvironmentstart.ps1 │ │ ├── invoke-d365lcsenvironmentstop.ps1 │ │ ├── invoke-d365lcsupload.ps1 │ │ ├── invoke-d365modulecompile.ps1 │ │ ├── invoke-d365modulefullcompile.ps1 │ │ ├── invoke-d365modulelabelgeneration.ps1 │ │ ├── invoke-d365modulereportscompile.ps1 │ │ ├── invoke-d365processmodule.ps1 │ │ ├── invoke-d365rearmwindows.ps1 │ │ ├── invoke-d365runbookanalyzer.ps1 │ │ ├── invoke-d365scdpbundleinstall.ps1 │ │ ├── invoke-d365sdpinstall.ps1 │ │ ├── invoke-d365sdpinstallude.ps1 │ │ ├── invoke-d365seleniumdownload.ps1 │ │ ├── invoke-d365sqlscript.ps1 │ │ ├── invoke-d365sysflushaodcache.ps1 │ │ ├── invoke-d365sysrunnerclass.ps1 │ │ ├── invoke-d365tablebrowser.ps1 │ │ ├── invoke-d365visualstudiocompilerresultanalyzer.ps1 │ │ ├── invoke-d365winrmcertificaterotation.ps1 │ │ ├── new-d365bacpac.ps1 │ │ ├── new-d365careport.ps1 │ │ ├── new-d365entraintegration.ps1 │ │ ├── new-d365isvlicense.ps1 │ │ ├── new-d365moduletoremove.ps1 │ │ ├── new-d365topologyfile.ps1 │ │ ├── publish-d365ssrsreport.ps1 │ │ ├── publish-d365webresources.ps1 │ │ ├── register-d365azurestorageconfig.ps1 │ │ ├── remove-d365broadcastmessageconfig.ps1 │ │ ├── remove-d365database.ps1 │ │ ├── remove-d365lcsassetfile.ps1 │ │ ├── remove-d365model.ps1 │ │ ├── remove-d365user.ps1 │ │ ├── rename-d365computername.ps1 │ │ ├── rename-d365instance.ps1 │ │ ├── repair-d365bacpacmodelfile.ps1 │ │ ├── restart-d365environment.ps1 │ │ ├── restore-d365devconfig.ps1 │ │ ├── restore-d365webconfig.ps1 │ │ ├── send-d365broadcastmessage.ps1 │ │ ├── set-d365activeazurestorageconfig.ps1 │ │ ├── set-d365activebroadcastmessageconfig.ps1 │ │ ├── set-d365admin.ps1 │ │ ├── set-d365azcopypath.ps1 │ │ ├── set-d365clickoncetrustprompt.ps1 │ │ ├── set-d365defaultmodelfornewprojects.ps1 │ │ ├── set-d365favoritebookmark.ps1 │ │ ├── set-d365flightservicecatalogid.ps1 │ │ ├── set-d365lcsapiconfig.ps1 │ │ ├── set-d365nugetpath.ps1 │ │ ├── set-d365offlineauthenticationadminemail.ps1 │ │ ├── set-d365rsatconfiguration.ps1 │ │ ├── set-d365rsattier2crypto.ps1 │ │ ├── set-d365sdpcleanup.ps1 │ │ ├── set-d365sqlpackagepath.ps1 │ │ ├── set-d365startpage.ps1 │ │ ├── set-d365sysadmin.ps1 │ │ ├── set-d365traceparserfilesize.ps1 │ │ ├── set-d365webconfigdatabase.ps1 │ │ ├── set-d365webservertype.ps1 │ │ ├── set-d365workstationmode.ps1 │ │ ├── start-d365environment.ps1 │ │ ├── start-d365environmentv2.ps1 │ │ ├── start-d365eventtrace.ps1 │ │ ├── stop-d365environment.ps1 │ │ ├── stop-d365eventtrace.ps1 │ │ ├── switch-d365activedatabase.ps1 │ │ ├── test-d365command.ps1 │ │ ├── test-d365dataverseconnection.ps1 │ │ ├── test-d365entraintegration.ps1 │ │ ├── test-d365flightservicecatalogid.ps1 │ │ ├── test-d365labelidisvalid.ps1 │ │ ├── update-d365bacpacmodelfilesingletable.ps1 │ │ └── update-d365user.ps1 │ ├── internal/ │ │ ├── configurations/ │ │ │ ├── configuration.ps1 │ │ │ └── readme.md │ │ ├── functions/ │ │ │ ├── add-aadusersecurity.ps1 │ │ │ ├── add-filetopackage.ps1 │ │ │ ├── backup-file.ps1 │ │ │ ├── complete-lcsuploadv2.ps1 │ │ │ ├── convert-hashtoargstringswitch.ps1 │ │ │ ├── convertto-booleanordefault.ps1 │ │ │ ├── convertto-hashtable.ps1 │ │ │ ├── convertto-pscustomobject.ps1 │ │ │ ├── copy-filetolcsblob.ps1 │ │ │ ├── get-applicationenvironment.ps1 │ │ │ ├── get-asyncresult.ps1 │ │ │ ├── get-axaggregatedimensions.ps1 │ │ │ ├── get-axaggregatemeasures.ps1 │ │ │ ├── get-axdataentities.ps1 │ │ │ ├── get-axforms.ps1 │ │ │ ├── get-axviews.ps1 │ │ │ ├── get-azureserviceobjective.ps1 │ │ │ ├── get-backupname.ps1 │ │ │ ├── get-canonicalidentityprovider.ps1 │ │ │ ├── get-compilerresult.ps1 │ │ │ ├── get-deepclone.ps1 │ │ │ ├── get-fileversion.ps1 │ │ │ ├── get-identityprovider.ps1 │ │ │ ├── get-instanceidentityprovider.ps1 │ │ │ ├── get-instancevalues.ps1 │ │ │ ├── get-lcsassetfilev2.ps1 │ │ │ ├── get-lcsassetvalidationstatusv2.ps1 │ │ │ ├── get-lcsdatabasebackupsv2.ps1 │ │ │ ├── get-lcsdatabaseoperationstatusv2.ps1 │ │ │ ├── get-lcsdeploymentstatusv2.ps1 │ │ │ ├── get-lcsenvironmenthistory.ps1 │ │ │ ├── get-lcsenvironmentmetadata.ps1 │ │ │ ├── get-lcsenvironmentrsatcertificate.ps1 │ │ │ ├── get-lcsfileasset.ps1 │ │ │ ├── get-lcssharedassetfile.ps1 │ │ │ ├── get-loginfromemail.ps1 │ │ │ ├── get-networkdomain.ps1 │ │ │ ├── get-productinfoprovider.ps1 │ │ │ ├── get-servicelist.ps1 │ │ │ ├── get-sqlcommand.ps1 │ │ │ ├── get-sqlparametersize.ps1 │ │ │ ├── get-sqlparametervalue.ps1 │ │ │ ├── get-sqlstring.ps1 │ │ │ ├── get-syncelements.ps1 │ │ │ ├── get-tenantfromemail.ps1 │ │ │ ├── get-timezone.ps1 │ │ │ ├── get-usersidfromaad.ps1 │ │ │ ├── get-windowsdefenderstatus.ps1 │ │ │ ├── import-aadapplicationIntod365fo.ps1 │ │ │ ├── import-aaduserIntod365fo.ps1 │ │ │ ├── import-assemblyfileintomemory.ps1 │ │ │ ├── import-generatereportassemblies.ps1 │ │ │ ├── invoke-azurebackuprestore.ps1 │ │ │ ├── invoke-clearazurespecificobjects.ps1 │ │ │ ├── invoke-clearsqlspecificobjects.ps1 │ │ │ ├── invoke-compilerresultanalyzer.ps1 │ │ │ ├── invoke-modelutil.ps1 │ │ │ ├── invoke-process.ps1 │ │ │ ├── invoke-requesthandler.ps1 │ │ │ ├── invoke-sqlbackuprestore.ps1 │ │ │ ├── invoke-sqlpackage.ps1 │ │ │ ├── invoke-timesignal.ps1 │ │ │ ├── new-d365foaadapplication.ps1 │ │ │ ├── new-d365fouser.ps1 │ │ │ ├── new-d365selfsignedcertificate.ps1 │ │ │ ├── new-decryptedfile.ps1 │ │ │ ├── new-webrequest.ps1 │ │ │ ├── publish-d365foresources.ps1 │ │ │ ├── readme.md │ │ │ ├── remove-lcsassetfile.ps1 │ │ │ ├── rename-configvalue.ps1 │ │ │ ├── repair-bacpacmodelqualifier.ps1 │ │ │ ├── repair-bacpacmodelsimpleandreplace.ps1 │ │ │ ├── select-defaultview.ps1 │ │ │ ├── set-adminuser.ps1 │ │ │ ├── set-azurebacpacvalues.ps1 │ │ │ ├── set-browserbookmark.ps1 │ │ │ ├── set-sqlbacpacvalues.ps1 │ │ │ ├── start-lcsdatabaseexportv2.ps1 │ │ │ ├── start-lcsdatabaserefreshv2.ps1 │ │ │ ├── start-lcsdeploymentv2.ps1 │ │ │ ├── start-lcsenvironmentstartstopv2.ps1 │ │ │ ├── start-lcsuploadv2.ps1 │ │ │ ├── test-aaduseridind365fo.ps1 │ │ │ ├── test-aaduserind365fo.ps1 │ │ │ ├── test-assembliesloaded.ps1 │ │ │ ├── test-configstoreagelocation.ps1 │ │ │ ├── test-pathexists.ps1 │ │ │ ├── test-registryvalue.ps1 │ │ │ ├── test-trustedconnection.ps1 │ │ │ ├── update-azurestoragevariables.ps1 │ │ │ ├── update-broadcastvariables.ps1 │ │ │ ├── update-lcsapivariables.ps1 │ │ │ ├── update-modulevariables.ps1 │ │ │ ├── update-psfconfigvariables.ps1 │ │ │ └── update-topologyfile.ps1 │ │ ├── misc/ │ │ │ ├── AzureDevOps.url │ │ │ ├── Bookmarks │ │ │ ├── D365FO.url │ │ │ ├── RepairBacpac.Qualifier.json │ │ │ ├── RepairBacpac.Replace.json │ │ │ └── RepairBacpac.Simple.json │ │ ├── scripts/ │ │ │ ├── enums.ps1 │ │ │ ├── license.ps1 │ │ │ ├── load-dotnet-assemblies.ps1 │ │ │ ├── postimport.ps1 │ │ │ ├── preimport.ps1 │ │ │ └── variables.ps1 │ │ ├── sql/ │ │ │ ├── add-aadapplicationintod365fo.sql │ │ │ ├── add-aaduserintod365fo.sql │ │ │ ├── add-bacpacdatabase.sql │ │ │ ├── backuprestoredb.sql │ │ │ ├── checkfornewazuredb.sql │ │ │ ├── clear-azurebacpacdatabase.sql │ │ │ ├── clear-d365tempdbtables.sql │ │ │ ├── clear-sqlbacpacdatabase.sql │ │ │ ├── disable-changetracking.sql │ │ │ ├── disable-flight.sql │ │ │ ├── disable-maintenancemode.sql │ │ │ ├── disable-user.sql │ │ │ ├── enable-changetracking.sql │ │ │ ├── enable-flight.sql │ │ │ ├── enable-maintenancemode.sql │ │ │ ├── enable-user.sql │ │ │ ├── get-alltablefields.sql │ │ │ ├── get-azureserviceobjective.sql │ │ │ ├── get-broadcastmessage.sql │ │ │ ├── get-broadcastmessageactive.sql │ │ │ ├── get-database.sql │ │ │ ├── get-flight.sql │ │ │ ├── get-instancevalues.sql │ │ │ ├── get-maintenancemode.sql │ │ │ ├── get-tablefields.sql │ │ │ ├── get-tables.sql │ │ │ ├── get-tablesequence.sql │ │ │ ├── get-tablesinchangedtracking.sql │ │ │ ├── get-user.sql │ │ │ ├── invoke-sphelp.sql │ │ │ ├── newazuredbfromcopy.sql │ │ │ ├── remove-database.sql │ │ │ ├── remove-user.sql │ │ │ ├── rename-computer.sql │ │ │ ├── set-aadusersecurityind365fo.sql │ │ │ ├── set-bacpacvaluesazure.sql │ │ │ ├── set-bacpacvaluessql.sql │ │ │ ├── set-sysadmin.sql │ │ │ ├── switch-database-tier1.sql │ │ │ ├── switch-database-tier2.sql │ │ │ ├── test-aaduseridind365fo.sql │ │ │ ├── test-aaduserind365fo.sql │ │ │ └── update-user.sql │ │ └── tepp/ │ │ ├── assignment.ps1 │ │ ├── eventtrace.tepp.ps1 │ │ ├── example.tepp.ps1 │ │ ├── lcs.tepp.ps1 │ │ ├── readme.md │ │ └── send-d365message.tepp.ps1 │ ├── readme.md │ ├── tests/ │ │ ├── examples/ │ │ │ ├── Get-DeepClone.Tests.ps1 │ │ │ ├── Import-D365Bacpac.Tests.ps1 │ │ │ └── Test-TrustedConnection.Tests.ps1 │ │ ├── functions/ │ │ │ ├── Add-D365AzureStorageConfig.Tests.ps1 │ │ │ ├── Add-D365BroadcastMessageConfig.Tests.ps1 │ │ │ ├── Add-D365ModuleToRemove.Tests.ps1 │ │ │ ├── Add-D365RsatWifConfigAuthorityThumbprint.Tests.ps1 │ │ │ ├── Add-D365WindowsDefenderRules.Tests.ps1 │ │ │ ├── Backup-D365DevConfig.Tests.ps1 │ │ │ ├── Backup-D365MetaDataDir.Tests.ps1 │ │ │ ├── Backup-D365Runbook.Tests.ps1 │ │ │ ├── Backup-D365WebConfig.Tests.ps1 │ │ │ ├── Backup-D365WifConfig.Tests.ps1 │ │ │ ├── Clear-D365ActiveBroadcastMessageConfig.Tests.ps1 │ │ │ ├── Clear-D365BacpacObject.Tests.ps1 │ │ │ ├── Clear-D365BacpacTableData.Tests.ps1 │ │ │ ├── Clear-D365MonitorData.Tests.ps1 │ │ │ ├── Clear-D365TempDbTables.Tests.ps1 │ │ │ ├── ConvertTo-D365Dacpac.Tests.ps1 │ │ │ ├── Disable-D365Exception.Tests.ps1 │ │ │ ├── Disable-D365Flight.Tests.ps1 │ │ │ ├── Disable-D365IISPreload.Tests.ps1 │ │ │ ├── Disable-D365MaintenanceMode.Tests.ps1 │ │ │ ├── Disable-D365SqlChangeTracking.Tests.ps1 │ │ │ ├── Disable-D365User.Tests.ps1 │ │ │ ├── Enable-D365Exception.Tests.ps1 │ │ │ ├── Enable-D365Flight.Tests.ps1 │ │ │ ├── Enable-D365IISPreload.Tests.ps1 │ │ │ ├── Enable-D365MaintenanceMode.Tests.ps1 │ │ │ ├── Enable-D365SqlChangeTracking.Tests.ps1 │ │ │ ├── Enable-D365User.Tests.ps1 │ │ │ ├── Export-D365BacpacModelFile.Tests.ps1 │ │ │ ├── Export-D365Model.Tests.ps1 │ │ │ ├── Export-D365SecurityDetails.Tests.ps1 │ │ │ ├── Find-D365Command.Tests.ps1 │ │ │ ├── Get-D365AOTObject.Tests.ps1 │ │ │ ├── Get-D365ActiveAzureStorageConfig.Tests.ps1 │ │ │ ├── Get-D365ActiveBroadcastMessageConfig.Tests.ps1 │ │ │ ├── Get-D365AzureDevOpsNuget.Tests.ps1 │ │ │ ├── Get-D365AzureStorageConfig.Tests.ps1 │ │ │ ├── Get-D365AzureStorageFile.Tests.ps1 │ │ │ ├── Get-D365AzureStorageUrl.Tests.ps1 │ │ │ ├── Get-D365BacpacSqlOptions.Tests.ps1 │ │ │ ├── Get-D365BacpacTable.Tests.ps1 │ │ │ ├── Get-D365BroadcastMessage.Tests.ps1 │ │ │ ├── Get-D365BroadcastMessageConfig.Tests.ps1 │ │ │ ├── Get-D365ClickOnceTrustPrompt.Tests.ps1 │ │ │ ├── Get-D365CompilerResult.Tests.ps1 │ │ │ ├── Get-D365Database.Tests.ps1 │ │ │ ├── Get-D365DatabaseAccess.Tests.ps1 │ │ │ ├── Get-D365DecryptedWebConfig.Tests.ps1 │ │ │ ├── Get-D365DefaultModelForNewProjects.Tests.ps1 │ │ │ ├── Get-D365DotNetClass.Tests.ps1 │ │ │ ├── Get-D365DotNetMethod.Tests.ps1 │ │ │ ├── Get-D365Environment.Tests.ps1 │ │ │ ├── Get-D365EnvironmentSettings.Tests.ps1 │ │ │ ├── Get-D365EventTraceProvider.Tests.ps1 │ │ │ ├── Get-D365ExternalIP.Tests.ps1 │ │ │ ├── Get-D365Flight.Tests.ps1 │ │ │ ├── Get-D365IISPreload.Tests.ps1 │ │ │ ├── Get-D365InstalledHotfix.Tests.ps1 │ │ │ ├── Get-D365InstalledPackage.Tests.ps1 │ │ │ ├── Get-D365InstalledService.Tests.ps1 │ │ │ ├── Get-D365InstanceName.Tests.ps1 │ │ │ ├── Get-D365JsonService.Tests.ps1 │ │ │ ├── Get-D365Label.Tests.ps1 │ │ │ ├── Get-D365LabelFile.Tests.ps1 │ │ │ ├── Get-D365Language.Tests.ps1 │ │ │ ├── Get-D365LcsApiConfig.Tests.ps1 │ │ │ ├── Get-D365LcsApiToken.Tests.ps1 │ │ │ ├── Get-D365LcsAssetFile.Tests.ps1 │ │ │ ├── Get-D365LcsAssetValidationStatus.Tests.ps1 │ │ │ ├── Get-D365LcsDatabaseBackups.Tests.ps1 │ │ │ ├── Get-D365LcsDatabaseOperationStatus.Tests.ps1 │ │ │ ├── Get-D365LcsDeploymentStatus.Tests.ps1 │ │ │ ├── Get-D365LcsEnvironmentHistory.Tests.ps1 │ │ │ ├── Get-D365LcsEnvironmentMetadata.Tests.ps1 │ │ │ ├── Get-D365LcsEnvironmentRsatCertificate.Tests.ps1 │ │ │ ├── Get-D365LcsSharedAssetFile.Tests.ps1 │ │ │ ├── Get-D365MaintenanceMode.Tests.ps1 │ │ │ ├── Get-D365Model.Tests.ps1 │ │ │ ├── Get-D365Module.Tests.ps1 │ │ │ ├── Get-D365OfflineAuthenticationAdminEmail.Tests.ps1 │ │ │ ├── Get-D365PackageBundleDetail.Tests.ps1 │ │ │ ├── Get-D365PackageLabelResourceFile.Tests.ps1 │ │ │ ├── Get-D365PackageLabelResources.Tests.ps1 │ │ │ ├── Get-D365ProductInformation.Tests.ps1 │ │ │ ├── Get-D365RsatCertificateThumbprint.Tests.ps1 │ │ │ ├── Get-D365RsatPlaybackFile.Tests.ps1 │ │ │ ├── Get-D365RsatSoapHostname.Tests.ps1 │ │ │ ├── Get-D365Runbook.Tests.ps1 │ │ │ ├── Get-D365RunbookId.Tests.ps1 │ │ │ ├── Get-D365RunbookLogFile.Tests.ps1 │ │ │ ├── Get-D365SDPCleanUp.Tests.ps1 │ │ │ ├── Get-D365SDPDetails.Tests.ps1 │ │ │ ├── Get-D365Table.Tests.ps1 │ │ │ ├── Get-D365TableField.Tests.ps1 │ │ │ ├── Get-D365TableSequence.Tests.ps1 │ │ │ ├── Get-D365TablesInChangedTracking.Tests.ps1 │ │ │ ├── Get-D365TfsUri.Tests.ps1 │ │ │ ├── Get-D365TfsWorkspace.Tests.ps1 │ │ │ ├── Get-D365Url.Tests.ps1 │ │ │ ├── Get-D365User.Tests.ps1 │ │ │ ├── Get-D365UserAuthenticationDetail.Tests.ps1 │ │ │ ├── Get-D365VisualStudioCompilerResult.Tests.ps1 │ │ │ ├── Get-D365WebServerType.Tests.ps1 │ │ │ ├── Get-D365WindowsActivationStatus.Tests.ps1 │ │ │ ├── Import-D365AadApplication.Tests.ps1 │ │ │ ├── Import-D365AadUser.Tests.ps1 │ │ │ ├── Import-D365Bacpac.Tests.ps1 │ │ │ ├── Import-D365Dacpac.Tests.ps1 │ │ │ ├── Import-D365ExternalUser.Tests.ps1 │ │ │ ├── Import-D365Model.Tests.ps1 │ │ │ ├── Import-D365RsatSelfServiceCertificates.Tests.ps1 │ │ │ ├── Initialize-D365RsatCertificate.Tests.ps1 │ │ │ ├── Install-D365SupportingSoftware.Tests.ps1 │ │ │ ├── Invoke-D365AzCopyTransfer.Tests.ps1 │ │ │ ├── Invoke-D365AzureDevOpsNugetPush.Tests.ps1 │ │ │ ├── Invoke-D365AzureStorageDownload.Tests.ps1 │ │ │ ├── Invoke-D365AzureStorageUpload.Tests.ps1 │ │ │ ├── Invoke-D365BestPractice.Tests.ps1 │ │ │ ├── Invoke-D365CompilerResultAnalyzer.Tests.ps1 │ │ │ ├── Invoke-D365DBSync.Tests.ps1 │ │ │ ├── Invoke-D365DBSyncPartial.Tests.ps1 │ │ │ ├── Invoke-D365DataFlush.Tests.ps1 │ │ │ ├── Invoke-D365DbSyncModule.Tests.ps1 │ │ │ ├── Invoke-D365GenerateReportAggregateDataEntity.Tests.ps1 │ │ │ ├── Invoke-D365GenerateReportAggregateMeasure.Tests.ps1 │ │ │ ├── Invoke-D365GenerateReportConfigKey.Tests.ps1 │ │ │ ├── Invoke-D365GenerateReportConfigKeyGroup.Tests.ps1 │ │ │ ├── Invoke-D365GenerateReportDataEntity.Tests.ps1 │ │ │ ├── Invoke-D365GenerateReportDataEntityField.Tests.ps1 │ │ │ ├── Invoke-D365GenerateReportKpi.Tests.ps1 │ │ │ ├── Invoke-D365GenerateReportLicenseCode.Tests.ps1 │ │ │ ├── Invoke-D365GenerateReportMenuItem.Tests.ps1 │ │ │ ├── Invoke-D365GenerateReportSsrs.Tests.ps1 │ │ │ ├── Invoke-D365GenerateReportTable.Tests.ps1 │ │ │ ├── Invoke-D365GenerateReportWorkflowType.Tests.ps1 │ │ │ ├── Invoke-D365GenerateReports.Tests.ps1 │ │ │ ├── Invoke-D365InstallAzCopy.Tests.ps1 │ │ │ ├── Invoke-D365InstallLicense.Tests.ps1 │ │ │ ├── Invoke-D365InstallNuget.Tests.ps1 │ │ │ ├── Invoke-D365InstallSqlPackage.Tests.ps1 │ │ │ ├── Invoke-D365LcsApiRefreshToken.Tests.ps1 │ │ │ ├── Invoke-D365LcsDatabaseExport.Tests.ps1 │ │ │ ├── Invoke-D365LcsDatabaseRefresh.Tests.ps1 │ │ │ ├── Invoke-D365LcsDeployment.Tests.ps1 │ │ │ ├── Invoke-D365LcsEnvironmentStart.Tests.ps1 │ │ │ ├── Invoke-D365LcsEnvironmentStop.Tests.ps1 │ │ │ ├── Invoke-D365LcsUpload.Tests.ps1 │ │ │ ├── Invoke-D365ModuleCompile.Tests.ps1 │ │ │ ├── Invoke-D365ModuleFullCompile.Tests.ps1 │ │ │ ├── Invoke-D365ModuleLabelGeneration.Tests.ps1 │ │ │ ├── Invoke-D365ModuleReportsCompile.Tests.ps1 │ │ │ ├── Invoke-D365ProcessModule.Tests.ps1 │ │ │ ├── Invoke-D365ReArmWindows.Tests.ps1 │ │ │ ├── Invoke-D365RunbookAnalyzer.Tests.ps1 │ │ │ ├── Invoke-D365SCDPBundleInstall.Tests.ps1 │ │ │ ├── Invoke-D365SDPInstall.Tests.ps1 │ │ │ ├── Invoke-D365SDPInstallUDE.Tests.ps1 │ │ │ ├── Invoke-D365SeleniumDownload.Tests.ps1 │ │ │ ├── Invoke-D365SqlScript.Tests.ps1 │ │ │ ├── Invoke-D365SysFlushAodCache.Tests.ps1 │ │ │ ├── Invoke-D365SysRunnerClass.Tests.ps1 │ │ │ ├── Invoke-D365TableBrowser.Tests.ps1 │ │ │ ├── Invoke-D365VisualStudioCompilerResultAnalyzer.Tests.ps1 │ │ │ ├── Invoke-D365WinRmCertificateRotation.Tests.ps1 │ │ │ ├── New-D365Bacpac.Tests.ps1 │ │ │ ├── New-D365CAReport.Tests.ps1 │ │ │ ├── New-D365EntraIntegration.Tests.ps1 │ │ │ ├── New-D365ISVLicense.Tests.ps1 │ │ │ ├── New-D365ModuleToRemove.Tests.ps1 │ │ │ ├── New-D365TopologyFile.Tests.ps1 │ │ │ ├── Publish-D365SsrsReport.Tests.ps1 │ │ │ ├── Publish-D365WebResources.Tests.ps1 │ │ │ ├── Register-D365AzureStorageConfig.Tests.ps1 │ │ │ ├── Remove-D365BroadcastMessageConfig.Tests.ps1 │ │ │ ├── Remove-D365Database.Tests.ps1 │ │ │ ├── Remove-D365LcsAssetFile.Tests.ps1 │ │ │ ├── Remove-D365Model.Tests.ps1 │ │ │ ├── Remove-D365User.Tests.ps1 │ │ │ ├── Rename-D365ComputerName.Tests.ps1 │ │ │ ├── Rename-D365Instance.Tests.ps1 │ │ │ ├── Repair-D365BacpacModelFile.Tests.ps1 │ │ │ ├── Restart-D365Environment.Tests.ps1 │ │ │ ├── Restore-D365DevConfig.Tests.ps1 │ │ │ ├── Restore-D365WebConfig.Tests.ps1 │ │ │ ├── Send-D365BroadcastMessage.Tests.ps1 │ │ │ ├── Set-D365ActiveAzureStorageConfig.Tests.ps1 │ │ │ ├── Set-D365ActiveBroadcastMessageConfig.Tests.ps1 │ │ │ ├── Set-D365Admin.Tests.ps1 │ │ │ ├── Set-D365AzCopyPath.Tests.ps1 │ │ │ ├── Set-D365ClickOnceTrustPrompt.Tests.ps1 │ │ │ ├── Set-D365DefaultModelForNewProjects.Tests.ps1 │ │ │ ├── Set-D365FavoriteBookmark.Tests.ps1 │ │ │ ├── Set-D365FlightServiceCatalogId.Tests.ps1 │ │ │ ├── Set-D365LcsApiConfig.Tests.ps1 │ │ │ ├── Set-D365NugetPath.Tests.ps1 │ │ │ ├── Set-D365OfflineAuthenticationAdminEmail.Tests.ps1 │ │ │ ├── Set-D365RsatConfiguration.Tests.ps1 │ │ │ ├── Set-D365RsatTier2Crypto.Tests.ps1 │ │ │ ├── Set-D365SDPCleanUp.Tests.ps1 │ │ │ ├── Set-D365SqlPackagePath.Tests.ps1 │ │ │ ├── Set-D365StartPage.Tests.ps1 │ │ │ ├── Set-D365SysAdmin.Tests.ps1 │ │ │ ├── Set-D365TraceParserFileSize.Tests.ps1 │ │ │ ├── Set-D365WebConfigDatabase.Tests.ps1 │ │ │ ├── Set-D365WebServerType.Tests.ps1 │ │ │ ├── Set-D365WorkstationMode.Tests.ps1 │ │ │ ├── Start-D365Environment.Tests.ps1 │ │ │ ├── Start-D365EnvironmentV2.Tests.ps1 │ │ │ ├── Start-D365EventTrace.Tests.ps1 │ │ │ ├── Stop-D365Environment.Tests.ps1 │ │ │ ├── Stop-D365EventTrace.Tests.ps1 │ │ │ ├── Switch-D365ActiveDatabase.Tests.ps1 │ │ │ ├── Test-D365Command.Tests.ps1 │ │ │ ├── Test-D365DataverseConnection.Tests.ps1 │ │ │ ├── Test-D365EntraIntegration.Tests.ps1 │ │ │ ├── Test-D365FlightServiceCatalogId.Tests.ps1 │ │ │ ├── Test-D365LabelIdIsValid.Tests.ps1 │ │ │ ├── Update-D365BacpacModelFileSingleTable.Tests.ps1 │ │ │ └── Update-D365User.Tests.ps1 │ │ ├── general/ │ │ │ ├── FileIntegrity.Exceptions.ps1 │ │ │ ├── FileIntegrity.Tests.ps1 │ │ │ ├── Help.Example.Parameters.Tests.ps1 │ │ │ ├── Help.Example.Tests.ps1 │ │ │ ├── Help.Exceptions.ps1 │ │ │ ├── Help.Tests.ps1 │ │ │ ├── Manifest.Tests.ps1 │ │ │ └── PSScriptAnalyzer.Tests.ps1 │ │ ├── pester-PSScriptAnalyzer.ps1 │ │ ├── pester.ps1 │ │ └── readme.md │ └── xml/ │ ├── d365fo.tools.Format.ps1xml │ ├── d365fo.tools.Types.ps1xml │ └── readme.md ├── docs/ │ ├── Add-D365AzureStorageConfig.md │ ├── Add-D365BroadcastMessageConfig.md │ ├── Add-D365ModuleToRemove.md │ ├── Add-D365RsatWifConfigAuthorityThumbprint.md │ ├── Add-D365WindowsDefenderRules.md │ ├── Backup-D365DevConfig.md │ ├── Backup-D365MetaDataDir.md │ ├── Backup-D365Runbook.md │ ├── Backup-D365WebConfig.md │ ├── Backup-D365WifConfig.md │ ├── Clear-D365ActiveBroadcastMessageConfig.md │ ├── Clear-D365BacpacObject.md │ ├── Clear-D365BacpacTableData.md │ ├── Clear-D365MonitorData.md │ ├── Clear-D365TempDbTables.md │ ├── ConvertTo-D365Dacpac.md │ ├── Disable-D365Exception.md │ ├── Disable-D365Flight.md │ ├── Disable-D365IISPreload.md │ ├── Disable-D365MaintenanceMode.md │ ├── Disable-D365SqlChangeTracking.md │ ├── Disable-D365User.md │ ├── Enable-D365Exception.md │ ├── Enable-D365Flight.md │ ├── Enable-D365IISPreload.md │ ├── Enable-D365MaintenanceMode.md │ ├── Enable-D365SqlChangeTracking.md │ ├── Enable-D365User.md │ ├── Export-D365BacpacModelFile.md │ ├── Export-D365Model.md │ ├── Export-D365SecurityDetails.md │ ├── Find-D365Command.md │ ├── Get-D365AOTObject.md │ ├── Get-D365ActiveAzureStorageConfig.md │ ├── Get-D365ActiveBroadcastMessageConfig.md │ ├── Get-D365AzureDevOpsNuget.md │ ├── Get-D365AzureStorageConfig.md │ ├── Get-D365AzureStorageFile.md │ ├── Get-D365AzureStorageUrl.md │ ├── Get-D365BacpacSqlOptions.md │ ├── Get-D365BacpacTable.md │ ├── Get-D365BroadcastMessage.md │ ├── Get-D365BroadcastMessageConfig.md │ ├── Get-D365ClickOnceTrustPrompt.md │ ├── Get-D365CompilerResult.md │ ├── Get-D365Database.md │ ├── Get-D365DatabaseAccess.md │ ├── Get-D365DecryptedWebConfig.md │ ├── Get-D365DefaultModelForNewProjects.md │ ├── Get-D365DotNetClass.md │ ├── Get-D365DotNetMethod.md │ ├── Get-D365Environment.md │ ├── Get-D365EnvironmentSettings.md │ ├── Get-D365EventTraceProvider.md │ ├── Get-D365ExternalIP.md │ ├── Get-D365Flight.md │ ├── Get-D365IISPreload.md │ ├── Get-D365InstalledHotfix.md │ ├── Get-D365InstalledPackage.md │ ├── Get-D365InstalledService.md │ ├── Get-D365InstanceName.md │ ├── Get-D365JsonService.md │ ├── Get-D365Label.md │ ├── Get-D365LabelFile.md │ ├── Get-D365Language.md │ ├── Get-D365LcsApiConfig.md │ ├── Get-D365LcsApiToken.md │ ├── Get-D365LcsAssetFile.md │ ├── Get-D365LcsAssetValidationStatus.md │ ├── Get-D365LcsDatabaseBackups.md │ ├── Get-D365LcsDatabaseOperationStatus.md │ ├── Get-D365LcsDeploymentStatus.md │ ├── Get-D365LcsEnvironmentHistory.md │ ├── Get-D365LcsEnvironmentMetadata.md │ ├── Get-D365LcsEnvironmentRsatCertificate.md │ ├── Get-D365LcsSharedAssetFile.md │ ├── Get-D365MaintenanceMode.md │ ├── Get-D365Model.md │ ├── Get-D365Module.md │ ├── Get-D365OfflineAuthenticationAdminEmail.md │ ├── Get-D365PackageBundleDetail.md │ ├── Get-D365PackageLabelResourceFile.md │ ├── Get-D365PackageLabelResources.md │ ├── Get-D365ProductInformation.md │ ├── Get-D365RsatCertificateThumbprint.md │ ├── Get-D365RsatPlaybackFile.md │ ├── Get-D365RsatSoapHostname.md │ ├── Get-D365Runbook.md │ ├── Get-D365RunbookId.md │ ├── Get-D365RunbookLogFile.md │ ├── Get-D365SDPCleanUp.md │ ├── Get-D365SDPDetails.md │ ├── Get-D365Table.md │ ├── Get-D365TableField.md │ ├── Get-D365TableSequence.md │ ├── Get-D365TablesInChangedTracking.md │ ├── Get-D365TfsUri.md │ ├── Get-D365TfsWorkspace.md │ ├── Get-D365Url.md │ ├── Get-D365User.md │ ├── Get-D365UserAuthenticationDetail.md │ ├── Get-D365VisualStudioCompilerResult.md │ ├── Get-D365WebServerType.md │ ├── Get-D365WindowsActivationStatus.md │ ├── Import-D365AadApplication.md │ ├── Import-D365AadUser.md │ ├── Import-D365Bacpac.md │ ├── Import-D365Dacpac.md │ ├── Import-D365ExternalUser.md │ ├── Import-D365Model.md │ ├── Import-D365RsatSelfServiceCertificates.md │ ├── Initialize-D365RsatCertificate.md │ ├── Install-D365SupportingSoftware.md │ ├── Invoke-D365AzCopyTransfer.md │ ├── Invoke-D365AzureDevOpsNugetPush.md │ ├── Invoke-D365AzureStorageDownload.md │ ├── Invoke-D365AzureStorageUpload.md │ ├── Invoke-D365BestPractice.md │ ├── Invoke-D365CompilerResultAnalyzer.md │ ├── Invoke-D365DBSync.md │ ├── Invoke-D365DBSyncPartial.md │ ├── Invoke-D365DataFlush.md │ ├── Invoke-D365DbSyncModule.md │ ├── Invoke-D365GenerateReportAggregateDataEntity.md │ ├── Invoke-D365GenerateReportAggregateMeasure.md │ ├── Invoke-D365GenerateReportConfigKey.md │ ├── Invoke-D365GenerateReportConfigKeyGroup.md │ ├── Invoke-D365GenerateReportDataEntity.md │ ├── Invoke-D365GenerateReportDataEntityField.md │ ├── Invoke-D365GenerateReportKpi.md │ ├── Invoke-D365GenerateReportLicenseCode.md │ ├── Invoke-D365GenerateReportMenuItem.md │ ├── Invoke-D365GenerateReportSsrs.md │ ├── Invoke-D365GenerateReportTable.md │ ├── Invoke-D365GenerateReportWorkflowType.md │ ├── Invoke-D365GenerateReports.md │ ├── Invoke-D365InstallAzCopy.md │ ├── Invoke-D365InstallLicense.md │ ├── Invoke-D365InstallNuget.md │ ├── Invoke-D365InstallSqlPackage.md │ ├── Invoke-D365LcsApiRefreshToken.md │ ├── Invoke-D365LcsDatabaseExport.md │ ├── Invoke-D365LcsDatabaseRefresh.md │ ├── Invoke-D365LcsDeployment.md │ ├── Invoke-D365LcsEnvironmentStart.md │ ├── Invoke-D365LcsEnvironmentStop.md │ ├── Invoke-D365LcsUpload.md │ ├── Invoke-D365ModuleCompile.md │ ├── Invoke-D365ModuleFullCompile.md │ ├── Invoke-D365ModuleLabelGeneration.md │ ├── Invoke-D365ModuleReportsCompile.md │ ├── Invoke-D365ProcessModule.md │ ├── Invoke-D365ReArmWindows.md │ ├── Invoke-D365RunbookAnalyzer.md │ ├── Invoke-D365SCDPBundleInstall.md │ ├── Invoke-D365SDPInstall.md │ ├── Invoke-D365SDPInstallUDE.md │ ├── Invoke-D365SeleniumDownload.md │ ├── Invoke-D365SqlScript.md │ ├── Invoke-D365SysFlushAodCache.md │ ├── Invoke-D365SysRunnerClass.md │ ├── Invoke-D365TableBrowser.md │ ├── Invoke-D365VisualStudioCompilerResultAnalyzer.md │ ├── Invoke-D365WinRmCertificateRotation.md │ ├── New-D365Bacpac.md │ ├── New-D365CAReport.md │ ├── New-D365EntraIntegration.md │ ├── New-D365ISVLicense.md │ ├── New-D365ModuleToRemove.md │ ├── New-D365TopologyFile.md │ ├── Publish-D365SsrsReport.md │ ├── Publish-D365WebResources.md │ ├── Register-D365AzureStorageConfig.md │ ├── Remove-D365BroadcastMessageConfig.md │ ├── Remove-D365Database.md │ ├── Remove-D365LcsAssetFile.md │ ├── Remove-D365Model.md │ ├── Remove-D365User.md │ ├── Rename-D365ComputerName.md │ ├── Rename-D365Instance.md │ ├── Repair-D365BacpacModelFile.md │ ├── Restart-D365Environment.md │ ├── Restore-D365DevConfig.md │ ├── Restore-D365WebConfig.md │ ├── Send-D365BroadcastMessage.md │ ├── Set-D365ActiveAzureStorageConfig.md │ ├── Set-D365ActiveBroadcastMessageConfig.md │ ├── Set-D365Admin.md │ ├── Set-D365AzCopyPath.md │ ├── Set-D365ClickOnceTrustPrompt.md │ ├── Set-D365DefaultModelForNewProjects.md │ ├── Set-D365FavoriteBookmark.md │ ├── Set-D365FlightServiceCatalogId.md │ ├── Set-D365LcsApiConfig.md │ ├── Set-D365NugetPath.md │ ├── Set-D365OfflineAuthenticationAdminEmail.md │ ├── Set-D365RsatConfiguration.md │ ├── Set-D365RsatTier2Crypto.md │ ├── Set-D365SDPCleanUp.md │ ├── Set-D365SqlPackagePath.md │ ├── Set-D365StartPage.md │ ├── Set-D365SysAdmin.md │ ├── Set-D365TraceParserFileSize.md │ ├── Set-D365WebConfigDatabase.md │ ├── Set-D365WebServerType.md │ ├── Set-D365WorkstationMode.md │ ├── Start-D365Environment.md │ ├── Start-D365EnvironmentV2.md │ ├── Start-D365EventTrace.md │ ├── Stop-D365Environment.md │ ├── Stop-D365EventTrace.md │ ├── Switch-D365ActiveDatabase.md │ ├── Test-D365Command.md │ ├── Test-D365DataverseConnection.md │ ├── Test-D365EntraIntegration.md │ ├── Test-D365FlightServiceCatalogId.md │ ├── Test-D365LabelIdIsValid.md │ ├── Update-D365BacpacModelFileSingleTable.md │ └── Update-D365User.md ├── install.ps1 ├── library/ │ └── d365fo.tools/ │ ├── d365fo.tools/ │ │ ├── Class1.cs │ │ └── d365fo.tools.csproj │ └── d365fo.tools.sln └── wiki/ ├── Azure-DevOps-Build-Configuration.md ├── Branching.md ├── Building-tools.md ├── Call-Internal-Functions.md ├── Calling-the-Table-Browser-from-the-browser.md ├── Configuration.md ├── Configure-Azure-Logic-App.md ├── Deprecation-guidelines.md ├── Do-And-Do-Not.md ├── Exception-handling.md ├── Fix-AzureStorageConfig.md ├── Getting-Started-with-GitHub.md ├── Home.md ├── How-To-Authenticate-With-LCS-API.md ├── How-To-Compile-Model.md ├── How-To-Download-Latest-Bacpac-From-Lcs.md ├── How-To-Enable-Users-In-Db.md ├── How-To-Export-Bacpac-From-Tier1.md ├── How-To-Import-Bacpac-Into-Tier1.md ├── How-To-Import-External-User-Into-Db.md ├── How-To-Import-User-Into-Db.md ├── How-To-Install-AzCopy.md ├── How-To-Install-NuGet.md ├── How-To-Install-SqlPackage.md ├── How-To-List-Models.md ├── How-To-Provision-Environment-Tier1.md ├── How-To-Register-NuGet-Source.md ├── How-To-Start-Stop-List-D365FO-Services.md ├── How-To-Transfer-Via-AzCopy.md ├── How-To-Update-Users-In-Db.md ├── How-To-Write-Wiki-Pages.md ├── Implementing-the-messaging-system.md ├── Load-individual-files-or-dot-source-the-files.md ├── Old-readme-examples.md ├── Open-the-path-where-D365FO.Tools-is-installed.md ├── Run-a-runnable-class.md ├── Troubleshoot.md ├── Tutorial-Import-Module.md ├── Tutorial-Install-Administrator.md ├── Tutorial-Install-Non-Administrator.md ├── Tutorial-List-Commands.md ├── Tutorial-Show-Help.md ├── Update-users-in-environment.md ├── Utilizing-the-configuration-system.md ├── Work-with-Azure-Storage-Account.md ├── Work-with-packages,-resource---label-files,-language-and-lables.md ├── Work-with-tables-and-fields.md ├── Working-with-the-different-D365-services.md └── _Sidebar.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ # Auto detect text files and perform LF normalization * text=auto ================================================ FILE: .github/workflows/Release-Management.yml ================================================ on: workflow_dispatch: inputs: gallery_publish: description: "Publish to the PowerShell Gallery?" default: true required: false type: boolean github_release: description: "Create a GitHub release?" default: true required: false type: boolean module_validation: description: "Module validation?" default: true required: false type: boolean jobs: call-tmpl-build-release: uses: fh-inway/d365.psmodule-alm/.github/workflows/tmpl-build-release.yml@main with: module: 'd365fo.tools' skippublish: not(${{ inputs.gallery_publish }}) skipghrelease: not(${{ inputs.github_release }}) skipValidation: not(${{ inputs.module_validation }}) secrets: apikey: ${{ secrets.ApiKey }} ================================================ FILE: .github/workflows/build-manual.yml ================================================ on: workflow_dispatch: inputs: skippublish: description: "Determines if the publishing to the PowerShell Gallery is skipped" default: $True required: false type: choice options: - $False - $True skipghrelease: description: "Determines if creation of a GitHub release is skipped" default: false required: false type: boolean skipValidation: description: "Determines if the module validation is skipped" default: false required: false type: boolean jobs: call-tmpl-build-release: uses: fh-inway/d365.psmodule-alm/.github/workflows/tmpl-build-release.yml@main with: module: 'd365fo.tools' skippublish: ${{ inputs.skippublish }} skipghrelease: ${{ inputs.skipghrelease }} skipValidation: ${{ inputs.skipValidation }} secrets: apikey: ${{ secrets.ApiKey }} ================================================ FILE: .github/workflows/build.yml ================================================ # run the Powershell scripts in build folder as part of a GitHub Action name: d365fo.tools-PR-Test on: push: branches: - master pull_request: workflow_dispatch: jobs: prerequisites: name: Prerequisites runs-on: windows-latest steps: - uses: actions/checkout@v4 - name: Cache Powershell Modules uses: actions/cache@v4 with: path: C:\Users\runneradmin\Documents\WindowsPowerShell\Modules key: 20210527|${{ hashFiles('**/vsts-prerequisites.ps1') }} - name: Prerequisites shell: powershell run: build\vsts-prerequisites.ps1 general-unit-tests: name: Validate General Unit Tests runs-on: windows-latest needs: prerequisites steps: - uses: actions/checkout@v4 - name: Cache Powershell Modules id: cache-powershell-modules uses: actions/cache@v4 with: path: C:\Users\runneradmin\Documents\WindowsPowerShell\Modules key: 20210527|${{ hashFiles('**/vsts-prerequisites.ps1') }} - name: Prerequisites if: steps.cache-powershell-modules.outputs.cache-hit != 'true' shell: powershell run: build\vsts-prerequisites.ps1 - name: Validate shell: powershell run: build\vsts-validate.ps1 -TestGeneral $true -TestFunctions $false -Exclude "PSScriptAnalyzer.Tests.ps1" - name: Publish Test Results **/TEST-*.xml if: always() uses: EnricoMi/publish-unit-test-result-action/windows@v2 with: files: '**/TEST-*.xml' check_name: 'General Unit Tests Results' comment_mode: 'off' public-functions-unit-tests: name: Validate Public Functions using PSScriptAnalyzer Unit Tests runs-on: windows-latest needs: prerequisites steps: - uses: actions/checkout@v4 - name: Cache Powershell Modules id: cache-powershell-modules uses: actions/cache@v4 with: path: C:\Users\runneradmin\Documents\WindowsPowerShell\Modules key: 20210527|${{ hashFiles('**/vsts-prerequisites.ps1') }} - name: Prerequisites if: steps.cache-powershell-modules.outputs.cache-hit != 'true' shell: powershell run: build\vsts-prerequisites.ps1 - name: Validate shell: powershell run: build\vsts-validate-psscriptanalyzer.ps1 -TestPublic $true -TestInternal $false - name: Publish Test Results **/TEST-*.xml if: always() uses: EnricoMi/publish-unit-test-result-action/windows@v2 with: files: '**/TEST-*.xml' check_name: 'Public Functions Unit Tests Results' comment_mode: 'off' internal-functions-unit-tests: name: Validate Internal Functions using PSScriptAnalyzer Unit Tests runs-on: windows-latest needs: Prerequisites steps: - uses: actions/checkout@v4 - name: Cache Powershell Modules id: cache-powershell-modules uses: actions/cache@v4 with: path: C:\Users\runneradmin\Documents\WindowsPowerShell\Modules key: 20210527|${{ hashFiles('**/vsts-prerequisites.ps1') }} - name: Prerequisites if: steps.cache-powershell-modules.outputs.cache-hit != 'true' shell: powershell run: build\vsts-prerequisites.ps1 - name: Validate shell: powershell run: build\vsts-validate-psscriptanalyzer.ps1 -TestPublic $false -TestInternal $true - name: Publish Test Results **/TEST-*.xml if: always() uses: EnricoMi/publish-unit-test-result-action/windows@v2 with: files: '**/TEST-*.xml' check_name: 'Internal Functions Unit Tests Results' comment_mode: 'off' individual-unit-tests: name: Validate Individual Unit Tests runs-on: windows-latest needs: prerequisites steps: - uses: actions/checkout@v4 - name: Cache Powershell Modules id: cache-powershell-modules uses: actions/cache@v4 with: path: C:\Users\runneradmin\Documents\WindowsPowerShell\Modules key: 20210527|${{ hashFiles('**/vsts-prerequisites.ps1') }} - name: Prerequisites if: steps.cache-powershell-modules.outputs.cache-hit != 'true' shell: powershell run: build\vsts-prerequisites.ps1 - name: Validate shell: powershell run: build\vsts-validate.ps1 -TestGeneral $false -TestFunctions $true - name: Publish Test Results **/TEST-*.xml if: always() uses: EnricoMi/publish-unit-test-result-action/windows@v2 with: files: '**/TEST-*.xml' check_name: 'Individual Unit Tests Results' comment_mode: 'off' ================================================ FILE: .github/workflows/dependencies.yml ================================================ # Used to define the dependencies of the d365fo.tools PowerShell module # in a way that can be evaluated for the GitHub dependency graph. # See https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-the-dependency-graph # The actual dependencies are defined in https://github.com/d365collaborative/d365fo.tools/blob/master/d365fo.tools/d365fo.tools.psd1 name: Dependencies on: workflow_dispatch: jobs: dependencies: steps: - name: PSFramework uses: PowershellFrameworkCollective/psframework@9b601d25f5831569ec42747be8053d6f6a50723d # version 1.9.308 - name: Azure.Storage uses: Azure/azure-powershell@v4.4.0-September2017 # unclear which commit/tag corresponds to https://www.powershellgallery.com/packages/Azure.Storage/4.4.0 - name: PSOAuthHelper uses: Splaxi/PSOAuthHelper@837a2da63bf76e86f339a4e43e38df5a3b82affe # version 0.3.0 - name: ImportExcel uses: dfinke/ImportExcel@v7.1.0 ================================================ FILE: .github/workflows/update-generated-text.yml ================================================ # Run the scrips documented in https://github.com/d365collaborative/d365fo.tools/wiki/Building-tools # Creates a pull request with the changes name: d365fo.tools-Generate-Text on: workflow_dispatch: jobs: generateText: name: Generate text runs-on: windows-latest steps: - uses: actions/checkout@v4 - name: Cache Powershell Modules id: cache-powershell-modules uses: actions/cache@v4 with: path: C:\Users\runneradmin\Documents\WindowsPowerShell\Modules key: 20210527|${{ hashFiles('**/vsts-prerequisites.ps1', '**/buildtools.ps1') }} - name: Prerequisites if: steps.cache-powershell-modules.outputs.cache-hit != 'true' shell: powershell run: build\vsts-prerequisites.ps1 - name: BuildTools if: steps.cache-powershell-modules.outputs.cache-hit != 'true' shell: powershell run: build\buildtools.ps1 - name: Format comment based help shell: powershell run: build\format-commentbasedhelp.ps1 - name: Generate parameter unit tests shell: powershell run: build\generate-parameterunittests.ps1 - name: Update documentation shell: powershell run: build\update-docs.ps1 - name: Generate Find-D365Command index shell: powershell run: build\generate-findcommandindex.ps1 - name: Create a pull request for changes uses: peter-evans/create-pull-request@v7 with: commit-message: | 🤖 Fix best practice deviations This pull request was automatically created by the d365fo.tools-Generate-Text action' title: '🤖 Fix best practice deviations' 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.' branch: 'update-generated-text/pull-request-patch-for-branch-${{ github.ref_name }}' ================================================ FILE: .github/workflows/update-wiki.yml ================================================ name: Wiki Update # Run when contents of the wiki folder are changed on: push: paths: - 'wiki/**' - 'docs/**' branches: - master # Allows you to run this workflow manually from the Actions tab workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Publish wiki folder to repository wiki uses: FH-Inway/github-wiki-publish-action@rsync with: path: "wiki/ docs" env: GH_PERSONAL_ACCESS_TOKEN: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} ================================================ FILE: .gitignore ================================================  # ignore the settings folder and files for VSCode and PSS .vscode/* *.psproj *TempPoint* # Ignore staging info from Visual Studio library/d365fo.tools/.vs/* library/d365fo.tools/d365fo.tools/bin/* library/d365fo.tools/d365fo.tools/obj/* # ignore PowerShell Studio MetaData d365fo.tools/d365fo.tools.psproj d365fo.tools/d365fo.tools.psproj.bak d365fo.tools/d365fo.tools.psprojs d365fo.tools/d365fo.tools.psproj # ignore the TestResults TestResults/* # ignore the publishing Directory publish/* ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2018 Mötz Jensen & Rasmus Andersen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # **d365fo.tools** A PowerShell module to handle different management tasks related to Microsoft Dynamics 365 Finance & Operations (D365FO). Read more about D365FO on [docs.microsoft.com](https://docs.microsoft.com/en-us/dynamics365/unified-operations/fin-and-ops/index). Available on PowerShell Gallery: [d365fo.tools](https://www.powershellgallery.com/packages/d365fo.tools). ## Table of contents * [Getting started](#getting-started) * [Getting help](#getting-help) * [Contributing](#contributing) * [Dependencies](#dependencies) ## Getting started ### Install the latest module ```PowerShell Install-Module -Name d365fo.tools ``` ### Install without administrator privileges ```PowerShell Install-Module -Name d365fo.tools -Scope CurrentUser ``` ### List all available commands / functions ```PowerShell Get-Command -Module d365fo.tools ``` ### Update the module ```PowerShell Update-Module -name d365fo.tools ``` ### Update the module - force ```PowerShell Update-Module -name d365fo.tools -Force ``` ## Getting help [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. Another way to learn about the different cmdlets available is to install the tools onto your D365FO developer box. You 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. Since 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. If 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. **Getting help inside the PowerShell console** Getting help is as easy as writing **Get-Help CommandName** ```PowerShell Get-Help New-D365Bacpac ``` *This will display the available default help.* Getting the entire help is as easy as writing **Get-Help CommandName -Full** ```PowerShell Get-Help New-D365Bacpac -Full ``` *This will display all available help content there is for the cmdlet / function* Getting all the available examples for a given command is as easy as writing **Get-Help CommandName -Examples** ```PowerShell Get-Help New-D365Bacpac -Examples ``` *This will display all the available **examples** for the cmdlet / function.* We 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. ### Web based help and examples We 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. The 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. They are also available in the [wiki](https://github.com/d365collaborative/d365fo.tools/wiki) in the list of pages. For 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. ## Contributing Want 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. ## Dependencies This 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. ================================================ FILE: build/buildtools.ps1 ================================================ # Installs the modules required for the automatic text generation. # See also https://github.com/d365collaborative/d365fo.tools/wiki/Building-tools Write-Host "Working on the machine named: $($env:computername)" Write-Host "The user running is: $($env:UserName)" $modules = @("PSModuleDevelopment", "platyPS") foreach ($item in $modules) { $module = Get-InstalledModule -Name $item -ErrorAction SilentlyContinue if ($null -eq $module) { Write-Host "Installing $item" -ForegroundColor Cyan Install-Module -Name $item -Force -Confirm:$false -Scope CurrentUser -AllowClobber -SkipPublisherCheck } Import-Module $item -Force Get-Module -Name $item } ================================================ FILE: build/filesAfter.txt ================================================ # List all files that are loaded in the postimport.ps1 # In the order they are loaded during postimport internal\configurations\*.ps1 internal\tepp\*.tepp.ps1 internal\tepp\assignment.ps1 internal\scripts\license.ps1 internal\scripts\variables.ps1 internal\scripts\load-dotnet-assemblies.ps1 ================================================ FILE: build/filesBefore.txt ================================================ # List all files that are loaded in the preimport.ps1 # In the order they are loaded during preimport internal\scripts\enums.ps1 ================================================ FILE: build/format-commentbasedhelp.ps1 ================================================ # Script to format the comments/documentation of the cmdlets used for the commend based help. # based on https://gist.github.com/Splaxi/ff7485a24f6ed9937f3e8da76b5d4840 # See also https://github.com/d365collaborative/d365fo.tools/wiki/Building-tools $path = "$PSScriptRoot\..\d365fo.tools" function Get-Header ($text) { $start = $text.IndexOf('<#') $temp = $start - 2 if($temp -gt 0) { $text.SubString(0, $start - 2) } else { "" } } function Format-Help ($text) { $start = $text.IndexOf('<#') $end = $text.IndexOf('#>') $help = $text.SubString($start + 2, $end - $start - 3) $skipfirst = $null # to avoid trailing spaces foreach ($newline in $help.Split("`n")) { if (-not $skipfirst) { $skipfirst = $true; continue } $trimmed = $newline.Trim() foreach ($line in $trimmed) { if ($line.StartsWith(".")) { " $line" } else { " $line" } } } } function Get-Body ($text) { $end = $text.IndexOf('#>') $text.SubString($end, $text.Length - $end) } $files = New-Object System.Collections.ArrayList $filesPublic = Get-ChildItem -Path "$path\functions\*.ps1" $files.AddRange($filesPublic) $filesInternal = Get-ChildItem -Path "$path\internal\functions\*.ps1" $files.AddRange($filesInternal) foreach ($file in $files) { $text = ($file | Get-Content -Raw).Trim() Set-Content -Path $file.FullName -Encoding UTF8 -Value (Get-Header $text).TrimEnd() Add-Content -Path $file.FullName -Encoding UTF8 -Value "<#".Trim() Add-Content -Path $file.FullName -Encoding UTF8 -Value (Format-Help $text) Add-Content -Path $file.FullName -Encoding UTF8 -Value (Get-Body $text).TrimEnd() -NoNewline } ================================================ FILE: build/generate-findcommandindex.ps1 ================================================ # Script to generate the comment based markdown help files. # See also https://github.com/d365collaborative/d365fo.tools/wiki/Building-tools $path = "$PSScriptRoot\.." Import-Module "$path\d365fo.tools" -Force $null = Find-D365Command -Rebuild -Verbose ================================================ FILE: build/generate-parameterunittests.ps1 ================================================ # Script to generate the parameter unit tests. # based on https://gist.github.com/Splaxi/2a24fc3c5193089ae7047ac5b8f104db # See also https://github.com/d365collaborative/d365fo.tools/wiki/Building-tools $path = "$PSScriptRoot\..\d365fo.tools" Import-Module $path -Force $excludeCommands = @() $commandsRaw = Get-Command -Module d365fo.tools -CommandType Function if ($excludeCommands.Count -gt 0) { $commands = $commandsRaw | Select-String -Pattern $excludeCommands -SimpleMatch -NotMatch } else { $commands = $commandsRaw } Remove-Item -Path "$path\tests\functions\*.Tests.ps1" foreach ( $commandName in $commands) { Invoke-PSMDTemplate CommandTest -OutPath "$path\tests\functions" -Name $commandName -Force } Get-ChildItem -Path "$path\tests\functions" -Recurse -File | Set-PSMDEncoding ================================================ FILE: build/update-docs.ps1 ================================================ # Script to generate the comment based markdown help files. # based on https://gist.github.com/Splaxi/8934e13cb35918d13af6e3a21c208b0e # See also https://github.com/d365collaborative/d365fo.tools/wiki/Building-tools $path = "$PSScriptRoot\.." Import-Module "$path\d365fo.tools" -Force Remove-Item -Path "$path\docs\*.md" $null = New-MarkdownHelp -Module d365fo.tools -OutputFolder "$path\docs" -Force Get-ChildItem -Path "$path\docs" -Recurse -File | Set-PSMDEncoding ================================================ FILE: build/vsts-build.ps1 ================================================ <# This script publishes the module to the gallery. It expects as input an ApiKey authorized to publish the module. Insert any build steps you may need to take before publishing it here. #> param ( $ModuleName = 'd365fo.tools', $Repository = 'PSGallery', $WorkingDirectory, $ApiKey, [switch] $SkipPublish, [switch] $AutoVersion ) #region Handle Working Directory Defaults if (-not $WorkingDirectory) { if ($env:RELEASE_PRIMARYARTIFACTSOURCEALIAS) { $WorkingDirectory = Join-Path -Path $env:SYSTEM_DEFAULTWORKINGDIRECTORY -ChildPath $env:RELEASE_PRIMARYARTIFACTSOURCEALIAS } else { $WorkingDirectory = $env:SYSTEM_DEFAULTWORKINGDIRECTORY } } if (-not $WorkingDirectory) { $WorkingDirectory = Split-Path $PSScriptRoot } #endregion Handle Working Directory Defaults # Prepare publish folder Write-PSFMessage -Level Important -Message "Creating and populating publishing directory" $publishDir = New-Item -Path $WorkingDirectory -Name publish -ItemType Directory Copy-Item -Path "$WorkingDirectory\$ModuleName" -Destination $publishDir.FullName -Recurse -Force # Create commands.ps1 $text = @() Get-ChildItem -Path "$($publishDir.FullName)\$ModuleName\internal\functions\" -Recurse -File -Filter "*.ps1" | ForEach-Object { $text += [System.IO.File]::ReadAllText($_.FullName) } Get-ChildItem -Path "$($publishDir.FullName)\$ModuleName\functions\" -Recurse -File -Filter "*.ps1" | ForEach-Object { $text += [System.IO.File]::ReadAllText($_.FullName) } $text -join "`n`n" | Set-Content -Path "$($publishDir.FullName)\$ModuleName\commands.ps1" # Create resourcesBefore.ps1 $processed = @() $text = @() foreach ($line in (Get-Content "$($PSScriptRoot)\filesBefore.txt" | Where-Object { $_ -notlike "#*" })) { if ([string]::IsNullOrWhiteSpace($line)) { continue } $basePath = Join-Path "$($publishDir.FullName)\$ModuleName" $line foreach ($entry in (Resolve-PSFPath -Path $basePath)) { $item = Get-Item $entry if ($item.PSIsContainer) { continue } if ($item.FullName -in $processed) { continue } $text += [System.IO.File]::ReadAllText($item.FullName) $processed += $item.FullName } } if ($text) { $text -join "`n`n" | Set-Content -Path "$($publishDir.FullName)\$ModuleName\resourcesBefore.ps1" } # Create resourcesAfter.ps1 $processed = @() $text = @() foreach ($line in (Get-Content "$($PSScriptRoot)\filesAfter.txt" | Where-Object { $_ -notlike "#*" })) { if ([string]::IsNullOrWhiteSpace($line)) { continue } $basePath = Join-Path "$($publishDir.FullName)\$ModuleName" $line foreach ($entry in (Resolve-PSFPath -Path $basePath)) { $item = Get-Item $entry if ($item.PSIsContainer) { continue } if ($item.FullName -in $processed) { continue } $text += [System.IO.File]::ReadAllText($item.FullName) $processed += $item.FullName } } if ($text) { $text -join "`n`n" | Set-Content -Path "$($publishDir.FullName)\$ModuleName\resourcesAfter.ps1" } #region Updating the Module Version if ($AutoVersion) { Write-PSFMessage -Level Important -Message "Updating module version numbers." try { [version]$remoteVersion = (Find-Module $ModuleName -Repository $Repository -ErrorAction Stop).Version } catch { Stop-PSFFunction -Message "Failed to access $Repository" -EnableException $true -ErrorRecord $_ } if (-not $remoteVersion) { Stop-PSFFunction -Message "Couldn't find $ModuleName on repository $Repository" -EnableException $true } $newBuildNumber = $remoteVersion.Build + 1 [version]$localVersion = (Import-PowerShellDataFile -Path "$($publishDir.FullName)\$ModuleName\$ModuleName.psd1").ModuleVersion Update-ModuleManifest -Path "$($publishDir.FullName)\$ModuleName\$ModuleName.psd1" -ModuleVersion "$($localVersion.Major).$($localVersion.Minor).$($newBuildNumber)" } #endregion Updating the Module Version # Publish to Gallery if ($SkipPublish) { return } Publish-Module -Path "$($publishDir.FullName)\$ModuleName" -NuGetApiKey $ApiKey -Force ================================================ FILE: build/vsts-prerequisites.ps1 ================================================ Write-Host "Working on the machine named: $($env:computername)" Write-Host "The user running is: $($env:UserName)" # $modules = @("PSFramework", "Az.Storage", "AzureAd", "PSNotification", "PSOAuthHelper", "PowerShellGet", "PackageManagement","ImportExcel","PSScriptAnalyzer") $modules = @("PSFramework", "PSScriptAnalyzer", "Az.Storage", "PSOAuthHelper", "ImportExcel") Write-Host "Installing Pester, maximum version 4.99.99" -ForegroundColor Cyan Install-Module "Pester" -MaximumVersion 4.99.99 -Force -Confirm:$false -Scope CurrentUser -AllowClobber -SkipPublisherCheck foreach ($item in $modules) { $module = Get-InstalledModule -Name $item -ErrorAction SilentlyContinue if ($null -eq $module) { Write-Host "Installing $item" -ForegroundColor Cyan Install-Module -Name $item -Force -Confirm:$false -Scope CurrentUser -AllowClobber -SkipPublisherCheck } Import-Module $item -Force Get-Module -Name $item } ================================================ FILE: build/vsts-validate-psscriptanalyzer.ps1 ================================================ param ( $TestPublic = $true, $TestInternal = $true ) # Guide for available variables and working with secrets: # https://docs.microsoft.com/en-us/vsts/build-release/concepts/definitions/build/variables?tabs=powershell # Needs to ensure things are Done Right and only legal commits to master get built # Run internal pester tests Write-Host "Working on the machine named: $($env:computername)" Write-Host "The user running is: $($env:UserName)" $modules = @("PSFramework", "PSScriptAnalyzer", "Az.Storage", "PSOAuthHelper", "ImportExcel") foreach ($item in $modules) { $module = Get-Module -Name $item -ErrorAction SilentlyContinue if ($null -eq $module) { Write-Host "Importing $item" -ForegroundColor Cyan Import-Module $item -Force } } Import-Module "Pester" -MaximumVersion 4.99.99 -Force & "$PSScriptRoot\..\d365fo.tools\tests\pester-PSScriptAnalyzer.ps1" -TestPublic $TestPublic -TestInternal $TestInternal ================================================ FILE: build/vsts-validate.ps1 ================================================ param ( $TestGeneral = $true, $TestFunctions = $true, $Exclude = "" ) # Guide for available variables and working with secrets: # https://docs.microsoft.com/en-us/vsts/build-release/concepts/definitions/build/variables?tabs=powershell # Needs to ensure things are Done Right and only legal commits to master get built # Run internal pester tests Write-Host "Working on the machine named: $($env:computername)" Write-Host "The user running is: $($env:UserName)" $modules = @("PSFramework", "PSScriptAnalyzer", "Az.Storage", "PSOAuthHelper", "ImportExcel") foreach ($item in $modules) { $module = Get-Module -Name $item -ErrorAction SilentlyContinue if ($null -eq $module) { Write-Host "Importing $item" -ForegroundColor Cyan Import-Module $item -Force } } Import-Module "Pester" -MaximumVersion 4.99.99 -Force & "$PSScriptRoot\..\d365fo.tools\tests\pester.ps1" -TestGeneral $TestGeneral -TestFunctions $TestFunctions -Exclude $Exclude ================================================ FILE: contributing.md ================================================ Here, we'll help you understand how to contribute to the project, and talk about fun stuff like styles and guidelines. # Contributing Let'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. There are several ways to contribute: - Create new commands (PowerShell/Dynamics 365 for Finance & Operations knowledge required) - Report bugs (everyone can do it) - Tests (Pester knowledge required) - Documentation: functions, website, this guide, everything can be improved (everyone can) - Code review (PowerShell/Dynamics 365 for Finance & Operations knowledge required) If you wanna help out to make the module even more robust - Standardize param names - Create tests for existing functions - Review existing function documentation ## Documentation Documentation 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. ## Contribute New Commands Start 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. ## Report Bugs [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. ## Fix Bugs If 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). [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. ## Branching Make sure to read our [branching guide](https://github.com/d365collaborative/d365fo.tools/wiki/Branching) on the wiki to get a good starting point. ## Automated build If 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) ## Standardize Parameters and Variables We chose to follow the standards below when creating parameters and variables for a function: 1) 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). 2) Any variable used in the parameter block **is required** to be singular. 3) Any variable not part of the parameter block, that is multiple words, will follow the camelCase format. (e.g. `$currentFile`, `$hotfixManifest`) 4) 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`). When 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) {...`. ## Tests Remember 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. ### How to write tests To 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: - "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. - Every one of the "IntegrationTests" may need to create a resource (e.g. a database). - Every resource should be named with the "d365fo.toolsci_" prefix. _The test should attempt to clean up after itself leaving a pristine environment._ - Try to write tests thinking they may run in each and every user's test environment. The 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. Tests 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. **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. ================================================ FILE: d365fo.tools/bin/d365fo.tools-index.json ================================================ [ { "CommandName": "Add-D365AzureStorageConfig", "Description": "Adds an Azure Storage Account config to the configuration store", "Tags": [ "Azure", "Azure Storage", "Config", "Configuration", "Token", "Blob", "Container" ], "Params": [ [ "Name", "The logical name of the Azure Storage Account you are about to registered in the configuration store", "", true, "false", "" ], [ "AccountId", "The account id for the Azure Storage Account you want to register in the configuration store", "", true, "false", "" ], [ "AccessToken", "The access token for the Azure Storage Account you want to register in the configuration store", "", true, "false", "" ], [ "SAS", "The SAS key that you have created for the storage account or blob container", "", true, "false", "" ], [ "Container", "The name of the blob container inside the Azure Storage Account you want to register in the configuration store", "Blobname,Blob", true, "false", "" ], [ "Temporary", "Instruct the cmdlet to only temporarily add the azure storage account configuration in the configuration store", "", false, "false", "False" ], [ "Force", "Switch to instruct the cmdlet to overwrite already registered Azure Storage Account entry", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Save an Azure Storage Account config", "Name": "Add-D365AzureStorageConfig", "Links": null, "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.", "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]" }, { "CommandName": "Add-D365BroadcastMessageConfig", "Description": "Adds a broadcast message config to the configuration store", "Tags": [ "Servicing", "Broadcast", "Message", "Users", "Environment", "Config", "Configuration", "ClientId", "ClientSecret" ], "Params": [ [ "Name", "The logical name of the broadcast configuration you are about to register in the configuration store", "", true, "false", "" ], [ "Tenant", "Azure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to send a message to", "$AADGuid", false, "false", "" ], [ "URL", "URL / URI for the D365FO environment you want to send a message to", "URI", false, "false", "" ], [ "ClientId", "The ClientId obtained from the Azure Portal when you created a Registered Application", "", false, "false", "" ], [ "ClientSecret", "The ClientSecret obtained from the Azure Portal when you created a Registered Application", "", false, "false", "" ], [ "TimeZone", "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\"", "", false, "false", "UTC" ], [ "EndingInMinutes", "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.", "", false, "false", "60" ], [ "OnPremise", "Specify if environnement is an D365 OnPremise\nDefault value is \"Not set\" (= Cloud Environnement)", "", false, "false", "False" ], [ "Temporary", "Instruct the cmdlet to only temporarily add the broadcast message configuration in the configuration store", "", false, "false", "False" ], [ "Force", "Instruct the cmdlet to overwrite the broadcast message configuration with the same name", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Save a broadcast message config", "Name": "Add-D365BroadcastMessageConfig", "Links": [ null, null, null, null, null, null ], "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.", "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]" }, { "CommandName": "Add-D365ModuleToRemove", "Description": "Modifies an existing deployable package and adds a ModuleToRemove.txt file to it.", "Params": [ [ "ModuleToRemove", "Path to the ModuleToRemove.txt file that you want to have inside a deployable package", "", true, "true (ByPropertyName)", "" ], [ "DeployablePackage", "Path to the deployable package file where the ModuleToRemove.txt file should be added", "", true, "false", "" ], [ "OutputPath", "Path where you want the generated deployable package to be stored\nDefault value is the same as the \"DeployablePackage\" parameter", "", false, "false", "$DeployablePackage" ] ], "Alias": "", "Author": "Florian Hopfner (@FH-Inway)", "Synopsis": "Adds a ModuleToRemove.txt file to a deployable package", "Name": "Add-D365ModuleToRemove", "Links": null, "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.", "Syntax": "Add-D365ModuleToRemove [-ModuleToRemove] \u003cString\u003e [-DeployablePackage] \u003cString\u003e [-OutputPath \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Add-D365RsatWifConfigAuthorityThumbprint", "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", "Tags": [ "RSAT", "Certificate", "Testing", "Regression Suite Automation Test", "Regression", "Test", "Automation" ], "Params": [ [ "CertificateThumbprint", "The thumbprint value of the certificate that you want to register in the wif.config file", "", true, "false", "" ] ], "Alias": "Add-D365WIFConfigAuthorityThumbprint", "Author": "Kenny Saelen (@kennysaelen)", "Synopsis": "Add a certificate thumbprint to the wif.config.", "Name": "Add-D365RsatWifConfigAuthorityThumbprint", "Links": null, "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.", "Syntax": "Add-D365RsatWifConfigAuthorityThumbprint [-CertificateThumbprint] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Add-D365WindowsDefenderRules", "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.", "Tags": [ "DevTools", "Developer", "Performance" ], "Params": [ [ "Silent", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Robin Kretzschmar (@darksmile92)", "Synopsis": "Add rules to Windows Defender to enhance performance during development.", "Name": "Add-D365WindowsDefenderRules", "Links": null, "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.", "Syntax": "Add-D365WindowsDefenderRules [-Silent] [\u003cCommonParameters\u003e]" }, { "CommandName": "Backup-D365DevConfig", "Description": "Will backup the DynamicsDevConfig.xml file located in the PackagesLocalDirectory\\Bin folder", "Tags": [ "Web Server", "IIS", "IIS Express", "Development" ], "Params": [ [ "OutputPath", "Path to the folder where you want the DynamicsDevConfig.xml file to be persisted\nDefault is: \"C:\\Temp\\d365fo.tools\\DevConfigBackup\"", "", false, "false", "$(Join-Path $Script:DefaultTempPath \"DevConfigBackup\")" ], [ "Force", "Instructs the cmdlet to overwrite the destination file if it already exists", "", false, "false", "False" ] ], "Alias": "", "Author": "Sander Holvoet (@smholvoet)", "Synopsis": "Backup the DynamicsDevConfig.xml file", "Name": "Backup-D365DevConfig", "Links": null, "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", "Syntax": "Backup-D365DevConfig [[-OutputPath] \u003cString\u003e] [-Force] [\u003cCommonParameters\u003e]" }, { "CommandName": "Backup-D365MetaDataDir", "Description": "Creates a backup of all the files and folders from the Metadata directory", "Tags": [ "PackagesLocalDirectory", "MetaData", "MetaDataDir", "MeteDataDirectory", "Backup", "Development" ], "Params": [ [ "MetaDataDir", "Path to the Metadata directory\nDefault value is the PackagesLocalDirectory", "", false, "false", "\"$Script:MetaDataDir\"" ], [ "BackupDir", "Path where you want the backup to be place", "", false, "false", "\"$($Script:MetaDataDir)_backup\"" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Create a backup of the Metadata directory", "Name": "Backup-D365MetaDataDir", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eBackup-D365MetaDataDir\nThis will backup the PackagesLocalDirectory and create an PackagesLocalDirectory_backup next to it", "Syntax": "Backup-D365MetaDataDir [[-MetaDataDir] \u003cString\u003e] [[-BackupDir] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Backup-D365Runbook", "Description": "Backup a runbook file for you to persist it for later analysis", "Tags": [ "Runbook", "Backup", "Analysis" ], "Params": [ [ "File", "Path to the file you want to backup", "Path", true, "true (ByPropertyName)", "" ], [ "DestinationPath", "Path to the folder where you want the backup file to be placed", "", false, "false", "$(Join-Path $Script:DefaultTempPath \"RunbookBackups\")" ], [ "Force", "Instructs the cmdlet to overwrite the destination file if it already exists", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Backup a runbook file", "Name": "Backup-D365Runbook", "Links": null, "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\\\".", "Syntax": "Backup-D365Runbook [-File] \u003cString\u003e [[-DestinationPath] \u003cString\u003e] [-Force] [\u003cCommonParameters\u003e]" }, { "CommandName": "Backup-D365WebConfig", "Description": "Will backup the web.config file located in the AOS / IIS folder", "Tags": [ "DEV", "Tier2", "DB", "Database", "Debug", "JIT", "LCS", "Azure DB" ], "Params": [ [ "OutputPath", "Path to the folder where you want the web.config file to be persisted\nDefault is: \"C:\\Temp\\d365fo.tools\\WebConfigBackup\"", "", false, "false", "$(Join-Path $Script:DefaultTempPath \"WebConfigBackup\")" ], [ "Force", "Instructs the cmdlet to overwrite the destination file if it already exists", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Backup the web.config file", "Name": "Backup-D365WebConfig", "Links": null, "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", "Syntax": "Backup-D365WebConfig [[-OutputPath] \u003cString\u003e] [-Force] [\u003cCommonParameters\u003e]" }, { "CommandName": "Backup-D365WifConfig", "Description": "Will backup the wif.config file located in the AOS / IIS folder", "Params": [ [ "OutputPath", "Path to the folder where you want the web.config file to be persisted\nDefault is: \"C:\\Temp\\d365fo.tools\\WifConfigBackup\"", "", false, "false", "$(Join-Path $Script:DefaultTempPath \"WifConfigBackup\")" ], [ "Force", "Instructs the cmdlet to overwrite the destination file if it already exists", "", false, "false", "False" ] ], "Alias": "", "Author": "Florian Hopfner (@FH-Inway)", "Synopsis": "Backup the wif.config file", "Name": "Backup-D365WifConfig", "Links": null, "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", "Syntax": "Backup-D365WifConfig [[-OutputPath] \u003cString\u003e] [-Force] [\u003cCommonParameters\u003e]" }, { "CommandName": "Clear-D365ActiveBroadcastMessageConfig", "Description": "Clear the active broadcast message config from the configuration store", "Tags": [ "Servicing", "Broadcast", "Message", "Users", "Environment", "Config", "Configuration", "ClientId", "ClientSecret" ], "Params": [ [ "Temporary", "Instruct the cmdlet to only temporarily clear the active broadcast message configuration in the configuration store", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Clear the active broadcast message config", "Name": "Clear-D365ActiveBroadcastMessageConfig", "Links": [ null, null, null, null, null, null ], "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eClear-D365ActiveBroadcastMessageConfig\nThis will clear the active broadcast message configuration from the configuration store.", "Syntax": "Clear-D365ActiveBroadcastMessageConfig [-Temporary] [\u003cCommonParameters\u003e]" }, { "CommandName": "Clear-D365BacpacObject", "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", "Params": [ [ "Path", "Path to the bacpac/dacpac or zip file that you want to work against", "BacpacFile,File", true, "false", "" ], [ "Name", "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", "ObjectName", true, "false", "" ], [ "ObjectType", "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\"", "", false, "false", "" ], [ "OutputPath", "Path to where you want the updated bacpac/dacpac or zip file to be saved", "", true, "false", "" ], [ "ClearFromSource", "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", "", true, "false", "False" ] ], "Alias": "", "Synopsis": "Clear out sql objects from inside the bacpac/dacpac or zip file", "Name": "Clear-D365BacpacObject", "Links": null, "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.", "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]" }, { "CommandName": "Clear-D365BacpacTableData", "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", "Tags": [ "Bacpac", "Servicing", "Data", "Deletion", "SqlPackage" ], "Params": [ [ "Path", "Path to the bacpac/dacpac or zip file that you want to work against", "BacpacFile,File", true, "false", "" ], [ "Table", "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", "TableName", true, "false", "" ], [ "OutputPath", "Path to where you want the updated bacpac/dacpac or zip file to be saved", "", true, "false", "" ], [ "ClearFromSource", "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", "", true, "false", "False" ] ], "Alias": "Clear-D365TableDataFromBacpac", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Clear out data for a table inside the bacpac/dacpac or zip file", "Name": "Clear-D365BacpacTableData", "Links": null, "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.", "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]" }, { "CommandName": "Clear-D365MonitorData", "Description": "Clear the monitoring data that is filling up the service drive on a Dynamics 365 for Finance \u0026 Operations", "Tags": [ "Monitor", "MonitorData", "MonitorAgent", "CleanUp", "Servicing" ], "Params": [ [ "Path", "The path to where the monitoring data is located\nThe default value is the \"ServiceDrive\" (j:\\ | k:\\) and the \\MonAgentData\\SingleAgent\\Tables folder structure", "", false, "true (ByValue, ByPropertyName)", "(Join-Path $script:ServiceDrive \"\\MonAgentData\\SingleAgent\\Tables\")" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Clear the monitoring data from a Dynamics 365 for Finance \u0026 Operations machine", "Name": "Clear-D365MonitorData", "Links": null, "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.", "Syntax": "Clear-D365MonitorData [[-Path] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Clear-D365TempDbTables", "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", "Params": [ [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "Days", "Temp tables older than this Days input will be dropped\nThe default value is 7 (days)", "", false, "false", "7" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Alex Kwitny (@AlexOnDAX)", "Synopsis": "Cleanup TempDB tables in Microsoft Dynamics 365 for Finance and Operations environment", "Name": "Clear-D365TempDbTables", "Links": [ "https://msdyn365fo.wordpress.com/2019/12/18/cleanup-tempdb-tables-in-a-msdyn365fo-sandbox-environment/", "https://github.com/PaulHeisterkamp/d365fo.blog/blob/master/Tools/SQL/DropTempDBTables.sql" ], "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.", "Syntax": "Clear-D365TempDbTables [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [[-Days] \u003cInt32\u003e] [-EnableException] [\u003cCommonParameters\u003e]" }, { "CommandName": "ConvertTo-D365Dacpac", "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", "Tags": [ "Bacpac", "Servicing", "Data", "SqlPackage", "Dacpac", "Table" ], "Params": [ [ "Path", "Path to the bacpac file that you want to work against\nIt can also be a zip file", "BacpacFile,File", true, "false", "" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Convert bacpac file to dacpac", "Name": "ConvertTo-D365Dacpac", "Links": null, "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.", "Syntax": "ConvertTo-D365Dacpac [-Path] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Disable-D365Exception", "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", "Tags": [ "Exception", "Exceptions", "Warning", "Warnings" ], "Params": [ ], "Alias": "", "Author": "Florian Hopfner (@FH-Inway)", "Synopsis": "Disables throwing of exceptions", "Name": "Disable-D365Exception", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eDisable-D365Exception\nThis will restore the default behavior of the module to not support throwing exceptions.", "Syntax": "Disable-D365Exception [\u003cCommonParameters\u003e]" }, { "CommandName": "Disable-D365Flight", "Description": "Provides a method for disabling a flight in D365FO.", "Tags": [ "Flight", "Flighting" ], "Params": [ [ "FlightName", "Name of the flight to disable", "", true, "false", "" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ] ], "Alias": "", "Author": "Frank Hüther (@FrankHuether)", "Synopsis": "Used to disable a flight", "Name": "Disable-D365Flight", "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", "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eDisable-D365Flight -FlightName DMFEnableAllCompanyExport\nDisables the flight DMFEnableAllCompanyExport", "Syntax": "Disable-D365Flight [-FlightName] \u003cString\u003e [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Disable-D365IISPreload", "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", "Params": [ ], "Alias": "", "Author": "Florian Hopfner (FH-Inway)", "Synopsis": "Disables IIS Preload for the AOSService application pool and website.", "Name": "Disable-D365IISPreload", "Links": [ null, null ], "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eDisable-D365IISPreload\nDisables IIS Preload for the AOSService application pool and website, restoring previous settings from backup if available.", "Syntax": "Disable-D365IISPreload [\u003cCommonParameters\u003e]" }, { "CommandName": "Disable-D365MaintenanceMode", "Description": "Sets the Dynamics 365 environment back into operating / running state after it has been in maintenance mode.", "Tags": [ "MaintenanceMode", "Maintenance", "License", "Configuration", "Servicing" ], "Params": [ [ "MetaDataDir", "The path to the meta data directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "\"$Script:MetaDataDir\"" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\"" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\MaintenanceMode\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@splaxi)", "Synopsis": "Sets the environment back into operating state", "Name": "Disable-D365MaintenanceMode", "Links": [ null, null ], "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.", "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]" }, { "CommandName": "Disable-D365SqlChangeTracking", "Description": "Disables the SQL Server Change Tracking for the environments database and all tables inside the database", "Tags": [ "MaintenanceMode", "Maintenance", "License", "Configuration", "Servicing" ], "Params": [ [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@splaxi)", "Synopsis": "Disable Change Tracking for the environment", "Name": "Disable-D365SqlChangeTracking", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eDisable-D365SqlChangeTracking\nThis will disable the Change Tracking on the Sql Server.", "Syntax": "Disable-D365SqlChangeTracking [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [-EnableException] [\u003cCommonParameters\u003e]" }, { "CommandName": "Disable-D365User", "Description": "Sets the enabled to 0 in the userinfo table.", "Tags": [ "User", "Users", "Security", "Configuration", "Permission" ], "Params": [ [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "Email", "The search string to select which user(s) should be disabled.\nThe parameter supports wildcards. E.g. -Email \"*@contoso.com*\"", "", false, "true (ByPropertyName)", "*" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Disables the user in D365FO", "Name": "Disable-D365User", "Links": null, "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", "Syntax": "Disable-D365User [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [[-Email] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Enable-D365Exception", "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", "Tags": [ "Exception", "Exceptions", "Warning", "Warnings" ], "Params": [ ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Enable exceptions to be thrown", "Name": "Enable-D365Exception", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eEnable-D365Exception\nThis will for the rest of the current PowerShell session make sure that exceptions will be thrown.", "Syntax": "Enable-D365Exception [\u003cCommonParameters\u003e]" }, { "CommandName": "Enable-D365Flight", "Description": "Provides a method for enabling a flight in D365FO.", "Tags": [ "Flight", "Flighting" ], "Params": [ [ "FlightName", "Name of the flight to enable", "", true, "false", "" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ] ], "Alias": "", "Author": "Frank Hüther (@FrankHuether)", "Synopsis": "Used to enable a flight", "Name": "Enable-D365Flight", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eEnable-D365Flight -FlightName DMFEnableAllCompanyExport\nEnables the flight DMFEnableAllCompanyExport", "Syntax": "Enable-D365Flight [-FlightName] \u003cString\u003e [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Enable-D365IISPreload", "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", "Params": [ [ "BaseUrl", "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", "", false, "false", "" ] ], "Alias": "", "Author": "Florian Hopfner (FH-Inway)", "Synopsis": "Enables IIS Preload for the AOSService application pool and website.", "Name": "Enable-D365IISPreload", "Links": [ null, null ], "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", "Syntax": "Enable-D365IISPreload [[-BaseUrl] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Enable-D365MaintenanceMode", "Description": "Sets the Dynamics 365 environment into maintenance mode to enable the user to update the license configuration", "Tags": [ "MaintenanceMode", "Maintenance", "License", "Configuration", "Servicing" ], "Params": [ [ "MetaDataDir", "The path to the meta data directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "\"$Script:MetaDataDir\"" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\"" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\MaintenanceMode\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@splaxi)", "Synopsis": "Sets the environment into maintenance mode", "Name": "Enable-D365MaintenanceMode", "Links": [ null, null ], "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.", "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]" }, { "CommandName": "Enable-D365SqlChangeTracking", "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", "Tags": [ "MaintenanceMode", "Maintenance", "License", "Configuration", "Servicing" ], "Params": [ [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@splaxi)", "Synopsis": "Enable Change Tracking for the environment", "Name": "Enable-D365SqlChangeTracking", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eEnable-D365SqlChangeTracking\nThis will enable the Change Tracking on the Sql Server.", "Syntax": "Enable-D365SqlChangeTracking [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [-EnableException] [\u003cCommonParameters\u003e]" }, { "CommandName": "Enable-D365User", "Description": "Sets the enabled to 1 in the userinfo table", "Tags": [ "User", "Users", "Security", "Configuration", "Permission" ], "Params": [ [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "Email", "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", "", false, "true (ByPropertyName)", "*" ] ], "Alias": "", "Author": "Mötz Jensen", "Synopsis": "Enables the user in D365FO", "Name": "Enable-D365User", "Links": null, "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", "Syntax": "Enable-D365User [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [[-Email] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Export-D365BacpacModelFile", "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", "Tags": [ "Bacpac", "Servicing", "Data", "SqlPackage", "Sql Server Options", "Collation" ], "Params": [ [ "Path", "Path to the bacpac file that you want to work against\nIt can also be a zip file", "BacpacFile,File", true, "false", "" ], [ "OutputPath", "Path to where you want the updated bacpac file to be saved\nDefault value is: \"c:\\temp\\d365fo.tools\"", "", false, "false", "$Script:DefaultTempPath" ], [ "Force", "Switch to instruct the cmdlet to overwrite the \"model.xml\" specified in the OutputPath", "", false, "false", "False" ] ], "Alias": "Get-D365ModelFileFromBacpac", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Extract the \"model.xml\" from the bacpac file", "Name": "Export-D365BacpacModelFile", "Links": null, "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.", "Syntax": "Export-D365BacpacModelFile [-Path] \u003cString\u003e [[-OutputPath] \u003cString\u003e] [-Force] [\u003cCommonParameters\u003e]" }, { "CommandName": "Export-D365Model", "Description": "Export a model from a Dynamics 365 for Finance \u0026 Operations environment", "Tags": [ "ModelUtil", "Axmodel", "Model", "Export" ], "Params": [ [ "Path", "Path to the folder where you want to save the model file", "File", true, "false", "" ], [ "Model", "Name of the model that you want to work against", "Modelname", true, "true (ByPropertyName)", "" ], [ "Force", "Instruct the cmdlet to overwrite already existing file", "", false, "false", "False" ], [ "BinDir", "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", "", false, "false", "\"$Script:PackageDirectory\\bin\"" ], [ "MetaDataDir", "The path to the meta data directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "\"$Script:MetaDataDir\"" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModelUtilExport\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Export a model from Dynamics 365 for Finance \u0026 Operations", "Name": "Export-D365Model", "Links": null, "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.", "Syntax": "Export-D365Model [-Path] \u003cString\u003e [-Model] \u003cString\u003e [-Force] [[-BinDir] \u003cString\u003e] [[-MetaDataDir] \u003cString\u003e] [[-LogPath] \u003cString\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\u003cCommonParameters\u003e]" }, { "CommandName": "Export-D365SecurityDetails", "Description": "Extracts and partitions the security details from an User Interface Security file into the same structure as AOT security files", "Tags": [ "Security", "Configuration", "Permission", "Development" ], "Params": [ [ "FilePath", "Path to the User Interface Security XML file you want to work against", "Path", true, "false", "" ], [ "OutputDirectory", "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\"", "Output", false, "false", "C:\\temp\\d365fo.tools\\security-extraction" ] ], "Alias": "", "Author": "Mötz Jensen (@splaxi)", "Synopsis": "Extract details from a User Interface Security file", "Name": "Export-D365SecurityDetails", "Links": null, "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\"", "Syntax": "Export-D365SecurityDetails [-FilePath] \u003cString\u003e [[-OutputDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Find-D365Command", "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", "Tags": [ "Find", "Help", "Command" ], "Params": [ [ "Pattern", "Searches help for all commands in d365fo.tools for the specified pattern and displays all results", "", false, "false", "" ], [ "Tag", "Finds all commands tagged with this auto-populated tag", "", false, "false", "" ], [ "Author", "Finds all commands tagged with this author", "", false, "false", "" ], [ "MinimumVersion", "Finds all commands tagged with this auto-populated minimum version", "", false, "false", "" ], [ "MaximumVersion", "Finds all commands tagged with this auto-populated maximum version", "", false, "false", "" ], [ "Rebuild", "Rebuilds the index", "", false, "false", "False" ], [ "EnableException", "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.", "Silent", false, "false", "False" ], [ "WhatIf", "Displays what would happen if the command is run", "wi", false, "false", "" ], [ "Confirm", "Confirms overwrite of index", "cf", false, "false", "" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Finds d365fo.tools commands searching through the inline help text", "Name": "Find-D365Command", "Links": null, "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)", "Syntax": "Find-D365Command [[-Pattern] \u003cString\u003e] [[-Tag] \u003cString[]\u003e] [[-Author] \u003cString\u003e] [[-MinimumVersion] \u003cString\u003e] [[-MaximumVersion] \u003cString\u003e] [-Rebuild] [-EnableException] [-WhatIf] [-Confirm] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365ActiveAzureStorageConfig", "Description": "Get active Azure Storage Account configuration object from the configuration store", "Tags": [ "Azure", "Azure Storage", "Config", "Configuration", "Token", "Blob", "Container" ], "Params": [ [ "OutputAsPsCustomObject", "Instruct the cmdlet to return a PsCustomObject object", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get active Azure Storage Account configuration", "Name": "Get-D365ActiveAzureStorageConfig", "Links": null, "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.", "Syntax": "Get-D365ActiveAzureStorageConfig [-OutputAsPsCustomObject] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365ActiveBroadcastMessageConfig", "Description": "Get active broadcast message configuration from the configuration store", "Tags": [ "Servicing", "Message", "Users", "Environment", "Config", "Configuration", "ClientId", "ClientSecret" ], "Params": [ [ "OutputAsHashtable", "Instruct the cmdlet to return a hastable object", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get active broadcast message configuration", "Name": "Get-D365ActiveBroadcastMessageConfig", "Links": [ null, null, null, null, null, null ], "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eGet-D365ActiveBroadcastMessageConfig\nThis will get the active broadcast message configuration.", "Syntax": "Get-D365ActiveBroadcastMessageConfig [-OutputAsHashtable] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365AOTObject", "Description": "Enables you to search for different AOT objects", "Params": [ [ "Path", "Path to the package that you want to work against", "PackageDirectory", true, "true (ByPropertyName)", "" ], [ "ObjectType", "The type of AOT object you\u0027re searching for", "Type", false, "false", "@(\"AxClass\")" ], [ "Name", "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", "", false, "false", "*" ], [ "SearchInPackages", "Switch to instruct the cmdlet to search in packages directly instead\r\nof searching in the XppMetaData directory under a given package", "", false, "false", "False" ], [ "IncludePath", "Switch to instruct the cmdlet to include the path for the object found", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Search for AOT object", "Name": "Get-D365AOTObject", "Links": null, "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.", "Syntax": "Get-D365AOTObject [-Path] \u003cString\u003e [[-ObjectType] \u003cString[]\u003e] [[-Name] \u003cString\u003e] [-SearchInPackages] [-IncludePath] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365AzureDevOpsNuget", "Description": "Get Azure DevOps nugets from a feed, to list all available details", "Params": [ [ "Url", "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.", "Uri", true, "false", "" ], [ "FeedName", "Name of the feed that you want to work against\nThe feed name is found under the Artifacts area in Azure DevOps", "", true, "false", "" ], [ "PeronalAccessToken", "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", "", true, "false", "" ], [ "Name", "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", "PackageName", false, "false", "*" ], [ "Latest", "Instruct the cmdlet to only fetch the latest package / nuget based on the version (highest)", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get Azure DevOps nugets", "Name": "Get-D365AzureDevOpsNuget", "Links": null, "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", "Syntax": "Get-D365AzureDevOpsNuget [-Url] \u003cString\u003e [-FeedName] \u003cString\u003e [-PeronalAccessToken] \u003cString\u003e [[-Name] \u003cString\u003e] [-Latest] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365AzureStorageConfig", "Description": "Get all Azure Storage Account configuration objects from the configuration store", "Tags": [ "Azure", "Azure Storage", "Config", "Configuration", "Token", "Blob", "Container" ], "Params": [ [ "Name", "The name of the Azure Storage Account you are looking for\nDefault value is \"*\" to display all Azure Storage Account configs", "", false, "false", "*" ], [ "OutputAsHashtable", "Instruct the cmdlet to return a hastable object", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get Azure Storage Account configs", "Name": "Get-D365AzureStorageConfig", "Links": null, "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.", "Syntax": "Get-D365AzureStorageConfig [[-Name] \u003cString\u003e] [-OutputAsHashtable] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365AzureStorageFile", "Description": "Get information for files from an Azure Storage Account", "Tags": [ "Azure", "Azure Storage", "Token", "Blob", "File", "Container" ], "Params": [ [ "AccountId", "Storage Account Name / Storage Account Id where file information should be retrieved from", "", false, "false", "$Script:AzureStorageAccountId" ], [ "AccessToken", "The token that has the needed permissions for the search action", "", false, "false", "$Script:AzureStorageAccessToken" ], [ "SAS", "The SAS key for the storage account or blob container", "", false, "false", "$Script:AzureStorageSAS" ], [ "Container", "Name of the blob container inside the storage account where file information should be retrieved from", "Blobname,Blob", false, "false", "$Script:AzureStorageContainer" ], [ "Name", "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", "FileName", false, "false", "*" ], [ "Latest", "Instruct the cmdlet to only fetch the information of the latest file from the Azure Storage Account", "GetLatest", true, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get file information from Azure Storage", "Name": "Get-D365AzureStorageFile", "Links": null, "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.", "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]" }, { "CommandName": "Get-D365AzureStorageUrl", "Description": "Get a valid blob container url from an Azure Storage Account", "Tags": [ "Azure", "Azure Storage", "Token", "Blob", "File", "Container", "LCS", "Asset", "Bacpac", "Backup" ], "Params": [ [ "AccountId", "Storage Account Name / Storage Account Id you want to work against", "", false, "false", "$Script:AzureStorageAccountId" ], [ "SAS", "The SAS key that you have created for the storage account or blob container", "", false, "false", "$Script:AzureStorageSAS" ], [ "Container", "Name of the blob container inside the storage account you want to work against", "Blobname,Blob", false, "false", "$Script:AzureStorageContainer" ], [ "OutputAsHashtable", "Instruct the cmdlet to return a hastable object", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get a blob Url from Azure Storage account", "Name": "Get-D365AzureStorageUrl", "Links": null, "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.", "Syntax": "Get-D365AzureStorageUrl [[-AccountId] \u003cString\u003e] [[-SAS] \u003cString\u003e] [[-Container] \u003cString\u003e] [-OutputAsHashtable] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365BacpacSqlOptions", "Description": "Extract the SQL Server options that are listed inside the model.xml file originating from a bacpac file", "Tags": [ "Bacpac", "Servicing", "Data", "SqlPackage", "Sql Server Options", "Collation" ], "Params": [ [ "Path", "Path to the extracted model.xml file that you want to work against", "File,ModelFile", false, "true (ByPropertyName)", "" ] ], "Alias": "Get-D365SqlOptionsFromBacpacModelFile", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the SQL Server options from the bacpac model.xml file", "Name": "Get-D365BacpacSqlOptions", "Links": null, "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.", "Syntax": "Get-D365BacpacSqlOptions [[-Path] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365BacpacTable", "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", "Tags": [ "Bacpac", "Servicing", "Data", "SqlPackage", "Table", "Size", "Troubleshooting" ], "Params": [ [ "Path", "Path to the bacpac file that you want to work against\nIt can also be a zip file", "BacpacFile,File", true, "false", "" ], [ "Table", "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", "", false, "false", "*" ], [ "Top", "Instruct the cmdlet with how many tables you want returned\nDefault is [int]::max, which translates into all tables present inside the bapcac file", "", false, "false", "2147483647" ], [ "SortSizeAsc", "Instruct the cmdlet to sort the output by size (original) ascending", "", false, "false", "False" ], [ "SortSizeDesc", "Instruct the cmdlet to sort the output by size (original) descending", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get tables from the bacpac file", "Name": "Get-D365BacpacTable", "Links": null, "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", "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]" }, { "CommandName": "Get-D365BroadcastMessage", "Description": "Get broadcast message from the D365FO environment by looking into the database table", "Tags": [ "Broadcast", "Message", "SysBroadcastMessage", "Servicing", "Message", "Users", "Environment" ], "Params": [ [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "ExcludeExpired", "Exclude all the records that has already expired", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get broadcast message from the D365FO environment", "Name": "Get-D365BroadcastMessage", "Links": null, "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.", "Syntax": "Get-D365BroadcastMessage [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [-ExcludeExpired] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365BroadcastMessageConfig", "Description": "Get all broadcast message configuration objects from the configuration store", "Tags": [ "Servicing", "Message", "Users", "Environment", "Config", "Configuration", "ClientId", "ClientSecret" ], "Params": [ [ "Name", "The name of the broadcast message configuration you are looking for\nDefault value is \"*\" to display all broadcast message configs", "", false, "false", "*" ], [ "OutputAsHashtable", "Instruct the cmdlet to return a hastable object", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get broadcast message configs", "Name": "Get-D365BroadcastMessageConfig", "Links": [ null, null, null, null, null, null ], "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.", "Syntax": "Get-D365BroadcastMessageConfig [[-Name] \u003cString\u003e] [-OutputAsHashtable] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365ClickOnceTrustPrompt", "Description": "Creates the needed registry keys and values for ClickOnce to work on the machine", "Tags": [ "ClickOnce", "Registry", "TrustPrompt" ], "Params": [ ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the ClickOnce configuration", "Name": "Get-D365ClickOnceTrustPrompt", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eGet-D365ClickOnceTrustPrompt\nThis will get the current ClickOnce configuration", "Syntax": "Get-D365ClickOnceTrustPrompt [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365CompilerResult", "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", "Tags": [ "Compiler", "Build", "Errors", "Warnings", "Tasks" ], "Params": [ [ "Path", "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", "LogFile", true, "true (ByValue, ByPropertyName)", "" ], [ "ErrorsOnly", "Instructs the cmdlet to only output compile results where there was errors detected", "", false, "false", "False" ], [ "OutputTotals", "Instructs the cmdlet to output the total errors and warnings after the analysis", "", false, "false", "False" ], [ "OutputAsObjects", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the compiler outputs presented", "Name": "Get-D365CompilerResult", "Links": null, "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", "Syntax": "Get-D365CompilerResult [-Path] \u003cString\u003e [-ErrorsOnly] [-OutputTotals] [-OutputAsObjects] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365Database", "Description": "Get the names of databases on either SQL Server or in Azure SQL Database instance", "Tags": [ "Database", "DB", "Servicing" ], "Params": [ [ "Name", "Name of the database that you are looking for\nDefault value is \"*\" which will show all databases", "", false, "false", "*" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get databases from the server", "Name": "Get-D365Database", "Links": null, "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.", "Syntax": "Get-D365Database [[-Name] \u003cString[]\u003e] [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365DatabaseAccess", "Description": "Gets all database information from the D365 environment", "Tags": [ "Database", "Connection", "Sql", "SqlUser", "SqlPwd" ], "Params": [ ], "Alias": "", "Author": "Rasmus Andersen (@ITRasmus)", "Synopsis": "Shows the Database Access information for the D365 Environment", "Name": "Get-D365DatabaseAccess", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eGet-D365DatabaseAccess\nThis will get all relevant details, including connection details, for the database configured for the environment", "Syntax": "Get-D365DatabaseAccess [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365DecryptedWebConfig", "Description": "Function used for decrypting the config file used by the D365 Finance \u0026 Operations AOS service", "Tags": [ "Configuration", "Service Account", "Sql", "SqlUser", "SqlPwd", "WebConfig", "Web.Config", "Decryption" ], "Params": [ [ "OutputPath", "Place where the decrypted files should be placed\nDefault value is: \"c:\\temp\\d365fo.tools\\WebConfigDecrypted\"", "", false, "false", "c:\\temp\\d365fo.tools\\WebConfigDecrypted" ], [ "AosServiceWebRootPath", "Location of the D365 webroot folder", "", false, "false", "$Script:AOSPath" ] ], "Alias": "Get-D365DecryptedConfigFile", "Synopsis": "Decrypts the AOS config file", "Name": "Get-D365DecryptedWebConfig", "Links": null, "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", "Syntax": "Get-D365DecryptedWebConfig [[-OutputPath] \u003cString\u003e] [[-AosServiceWebRootPath] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365DefaultModelForNewProjects", "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", "Params": [ ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the default model used creating new projects in Visual Studio", "Name": "Get-D365DefaultModelForNewProjects", "Links": null, "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.", "Syntax": "Get-D365DefaultModelForNewProjects [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365DotNetClass", "Description": "Get a .NET class from an assembly file (dll) from the package directory", "Tags": [ ".Net", "DotNet", "Class", "Development" ], "Params": [ [ "Name", "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", "", false, "false", "*" ], [ "Assembly", "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", "", false, "false", "*.dll" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get a .NET class from the Dynamics 365 for Finance and Operations installation", "Name": "Get-D365DotNetClass", "Links": null, "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", "Syntax": "Get-D365DotNetClass [[-Name] \u003cString\u003e] [[-Assembly] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365DotNetMethod", "Description": "Get a .NET method from an assembly file (dll) from the package directory", "Tags": [ ".Net", "DotNet", "Class", "Method", "Methods", "Development" ], "Params": [ [ "Assembly", "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", "File", true, "true (ByPropertyName)", "" ], [ "Name", "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", "MethodName", false, "false", "*" ], [ "TypeName", "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", "ClassName", false, "false", "*" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get a .NET method from the Dynamics 365 for Finance and Operations installation", "Name": "Get-D365DotNetMethod", "Links": null, "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*\"", "Syntax": "Get-D365DotNetMethod [-Assembly] \u003cString\u003e [[-Name] \u003cString\u003e] [[-TypeName] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365Environment", "Description": "List status for all relevant services that is running in a D365FO environment", "Tags": [ "Environment", "Service", "Services", "Aos", "Batch", "Servicing" ], "Params": [ [ "ComputerName", "An array of computers that you want to query for the services status on.", "", false, "false", "@($env:computername)" ], [ "All", "Set when you want to query all relevant services\nIncludes:\r\nAos\r\nBatch\r\nFinancial Reporter\r\nDMF", "", false, "false", "True" ], [ "Aos", "Instruct the cmdlet to query the AOS (IIS) service", "", false, "false", "False" ], [ "Batch", "Instruct the cmdlet query the batch service", "", false, "false", "False" ], [ "FinancialReporter", "Instruct the cmdlet query the financial reporter (Management Reporter 2012)", "", false, "false", "False" ], [ "DMF", "Instruct the cmdlet query the DMF service", "", false, "false", "False" ], [ "OnlyStartTypeAutomatic", "Instruct the cmdlet to filter out services that are set to manual start or disabled", "", false, "false", "False" ], [ "OutputServiceDetailsOnly", "Instruct the cmdlet to exclude the server name from the output", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Cmdlet to get the current status for the different services in a Dynamics 365 Finance \u0026 Operations environment", "Name": "Get-D365Environment", "Links": null, "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.", "Syntax": "Get-D365Environment [[-ComputerName] \u003cString[]\u003e] [-All] [-OnlyStartTypeAutomatic] [-OutputServiceDetailsOnly] [\u003cCommonParameters\u003e]\nGet-D365Environment [[-ComputerName] \u003cString[]\u003e] [-Aos] [-Batch] [-FinancialReporter] [-DMF] [-OnlyStartTypeAutomatic] [-OutputServiceDetailsOnly] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365EnvironmentSettings", "Description": "Gets all settings the Dynamics 365 for Finance \u0026 Operations environment uses.", "Tags": [ "Environment", "Configuration", "WebConfig", "Web.Config", "Decryption" ], "Params": [ ], "Alias": "", "Author": "Rasmus Andersen (@ITRasmus)", "Synopsis": "Get the D365FO environment settings", "Name": "Get-D365EnvironmentSettings", "Links": null, "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.", "Syntax": "Get-D365EnvironmentSettings [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365EventTraceProvider", "Description": "Get the full list of available Event Trace Providers for Dynamics 365 for Finance and Operations", "Tags": [ "ETL", "EventTracing", "EventTrace" ], "Params": [ [ "Name", "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", "", false, "false", "@(\"*\")" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get D365FO Event Trace Provider", "Name": "Get-D365EventTraceProvider", "Links": null, "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.", "Syntax": "Get-D365EventTraceProvider [[-Name] \u003cString[]\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365ExternalIP", "Description": "Get the external IP address by calling an external webpage and interpret the result from that", "Tags": [ "DEV", "Tier2", "DB", "Database", "Debug", "JIT", "LCS", "Azure DB", "IP" ], "Params": [ [ "SaveToClipboard", "Instruct the cmdlet to copy the IP address directly into the clipboard, to save you the trouble", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the external IP address", "Name": "Get-D365ExternalIP", "Links": null, "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", "Syntax": "Get-D365ExternalIP [-SaveToClipboard] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365Flight", "Description": "Provides a method for listing a flight in D365FO.", "Tags": [ "Flight", "Flighting" ], "Params": [ [ "FlightName", "Name of the flight that you are looking for\nSupports wildcards \"*\"", "", false, "false", "*" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Used to get a flight", "Name": "Get-D365Flight", "Links": null, "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", "Syntax": "Get-D365Flight [[-FlightName] \u003cString\u003e] [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365IISPreload", "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)", "Params": [ ], "Alias": "", "Author": "Florian Hopfner (FH-Inway)", "Synopsis": "Gets IIS Preload status for the AOSService application pool and website.", "Name": "Get-D365IISPreload", "Links": [ null, null ], "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eGet-D365IISPreload\nRetrieves the IIS Preload configuration for the AOSService application pool and website.", "Syntax": "Get-D365IISPreload [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365InstalledHotfix", "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.", "Tags": [ "Hotfix", "Servicing", "Model", "Models", "KB", "Patch", "Patching", "PackagesLocalDirectory" ], "Params": [ [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the AOS Service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "Path to the PackagesLocalDirectory\nDefault path is the same as the AOS Service PackagesLocalDirectory", "", false, "false", "$Script:PackageDirectory" ], [ "Model", "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", "", false, "false", "*" ], [ "Name", "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", "", false, "false", "*" ], [ "KB", "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", "", false, "false", "*" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get installed hotfix (DEPRECATED)", "Name": "Get-D365InstalledHotfix", "Links": null, "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", "Syntax": "Get-D365InstalledHotfix [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [[-Model] \u003cString\u003e] [[-Name] \u003cString\u003e] [[-KB] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365InstalledPackage", "Description": "Get installed package from the machine running the AOS service for Dynamics 365 Finance \u0026 Operations", "Tags": [ "PackagesLocalDirectory", "Servicing", "Model", "Models", "Package", "Packages" ], "Params": [ [ "Name", "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", "", false, "false", "*" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get installed package from Dynamics 365 Finance \u0026 Operations environment", "Name": "Get-D365InstalledPackage", "Links": null, "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", "Syntax": "Get-D365InstalledPackage [[-Name] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365InstalledService", "Description": "Get installed Dynamics 365 for Finance \u0026 Operations services that are installed on the machine", "Tags": [ "Services", "Servicing", "Topology" ], "Params": [ [ "Path", "Path to the folder that contains the \"InstallationRecords\" folder", "", false, "false", "$Script:InstallationRecordsDir" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get installed D365 services", "Name": "Get-D365InstalledService", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eGet-D365InstalledService\nThis will get all installed services on the machine.", "Syntax": "Get-D365InstalledService [[-Path] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365InstanceName", "Description": "Get the instance name that is registered in the environment", "Tags": [ "Instance", "Servicing" ], "Params": [ ], "Alias": "", "Author": "Rasmus Andersen (@ITRasmus)", "Synopsis": "Gets the instance name", "Name": "Get-D365InstanceName", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eGet-D365InstanceName\nThis will get the service name that the environment has configured", "Syntax": "Get-D365InstanceName [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365JsonService", "Description": "Get Json based services that are available from a Dynamics 365 Finance \u0026 Operations environment", "Tags": [ "DMF", "OData", "RestApi", "Data Management Framework" ], "Params": [ [ "Name", "The name of the json service that you are looking for\nDefault value is \"*\" to display all json services", "", false, "false", "*" ], [ "Url", "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\"", "", true, "false", "" ], [ "Tenant", "Azure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to access", "", true, "false", "" ], [ "ClientId", "The ClientId obtained from the Azure Portal when you created a Registered Application", "", true, "false", "" ], [ "ClientSecret", "The ClientSecret obtained from the Azure Portal when you created a Registered Application", "", true, "false", "" ], [ "RawOutput", "Instructs the cmdlet to include the outer structure of the response received from the endpoint\nThe output will still be a PSCustomObject", "", false, "false", "False" ], [ "OutputAsJson", "Instructs the cmdlet to convert the output to a Json string", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get Json based service", "Name": "Get-D365JsonService", "Links": null, "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\".", "Syntax": "Get-D365JsonService [[-Name] \u003cString\u003e] [-Url] \u003cString\u003e [-Tenant] \u003cString\u003e [-ClientId] \u003cString\u003e [-ClientSecret] \u003cString\u003e [-RawOutput] [-OutputAsJson] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365Label", "Description": "Get label from the label file from the running the Dynamics 365 Finance \u0026 Operations instance", "Tags": [ "PackagesLocalDirectory", "Servicing", "Language", "Labels", "Label" ], "Params": [ [ "BinDir", "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", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "LabelFileId", "Name / Id of the label \"file\" that you want to work against", "", true, "true (ByPropertyName)", "" ], [ "Language", "Name / string representation of the language / culture you want to work against\nDefault value is \"en-US\"", "", false, "true (ByPropertyName)", "en-US" ], [ "Name", "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", "", false, "false", "*" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get label from the label file from Dynamics 365 Finance \u0026 Operations environment", "Name": "Get-D365Label", "Links": null, "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)", "Syntax": "Get-D365Label [[-BinDir] \u003cString\u003e] [-LabelFileId] \u003cString\u003e [[-Language] \u003cString[]\u003e] [[-Name] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365LabelFile", "Description": "Get label file (ids) for packages / modules from the machine running the AOS service for Dynamics 365 Finance \u0026 Operations", "Tags": [ "PackagesLocalDirectory", "Servicing", "Language", "Labels", "Label" ], "Params": [ [ "BinDir", "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", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ], [ "Module", "Name of the module that you want to work against\nDefault value is \"*\" which will search for all modules", "ModuleName", false, "true (ByPropertyName)", "*" ], [ "Name", "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)", "", false, "false", "*" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get label file (ids) for packages / modules from Dynamics 365 Finance \u0026 Operations environment", "Name": "Get-D365LabelFile", "Links": null, "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", "Syntax": "Get-D365LabelFile [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [[-Module] \u003cString\u003e] [[-Name] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365Language", "Description": "Get installed languages from the running the Dynamics 365 Finance \u0026 Operations instance", "Tags": [ "PackagesLocalDirectory", "Servicing", "Language", "Labels", "Label" ], "Params": [ [ "BinDir", "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", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "Name", "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", "", false, "false", "*" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get installed languages from Dynamics 365 Finance \u0026 Operations environment", "Name": "Get-D365Language", "Links": null, "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)", "Syntax": "Get-D365Language [[-BinDir] \u003cString\u003e] [[-Name] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365LcsApiConfig", "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", "Tags": [ "Environment", "Url", "Config", "Configuration", "LCS", "Upload", "ClientId" ], "Params": [ [ "OutputAsHashtable", "Instruct the cmdlet to return a hashtable object", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the LCS configuration details", "Name": "Get-D365LcsApiConfig", "Links": [ null, null, null, null, null, null, null ], "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.", "Syntax": "Get-D365LcsApiConfig [-OutputAsHashtable] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365LcsApiToken", "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", "Tags": [ "Environment", "Url", "Config", "Configuration", "LCS", "Upload", "Api", "AAD", "Token" ], "Params": [ [ "ClientId", "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", "", false, "false", "$Script:LcsApiClientId" ], [ "Username", "The username of the account that you want to impersonate\nIt can either be your personal account or a service account", "", true, "false", "" ], [ "Password", "The password of the account that you want to impersonate", "", true, "false", "" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get a valid OAuth 2.0 access token for LCS", "Name": "Get-D365LcsApiToken", "Links": [ null, null, null, null, null, null, null ], "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.", "Syntax": "Get-D365LcsApiToken [[-ClientId] \u003cString\u003e] [-Username] \u003cString\u003e [-Password] \u003cString\u003e [[-LcsApiUri] \u003cString\u003e] [-EnableException] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365LcsAssetFile", "Description": "Get the available files from the Asset Library in LCS project", "Params": [ [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS\nDefault value can be configured using Set-D365LcsApiConfig", "", false, "false", "$Script:LcsApiProjectId" ], [ "FileType", "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\"", "", false, "false", "SoftwareDeployablePackage" ], [ "AssetName", "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", "", false, "false", "*" ], [ "AssetVersion", "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", "", false, "false", "*" ], [ "AssetFilename", "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", "", false, "false", "*" ], [ "AssetDescription", "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", "", false, "false", "*" ], [ "AssetId", "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", "", false, "false", "*" ], [ "BearerToken", "The token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "Latest", "Instruct the cmdlet to only fetch the latest file from the Asset Library from LCS", "GetLatest", false, "false", "False" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get file from the Asset library inside the LCS project", "Name": "Get-D365LcsAssetFile", "Links": [ null, null, null, null, null ], "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.", "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]" }, { "CommandName": "Get-D365LcsAssetValidationStatus", "Description": "Get the validation status for a given file in the Asset Library in LCS", "Params": [ [ "AssetId", "The unique id of the asset / file that you are trying to deploy from LCS", "", true, "true (ByPropertyName)", "" ], [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS\nDefault value can be configured using Set-D365LcsApiConfig", "", false, "false", "$Script:LcsApiProjectId" ], [ "BearerToken", "The token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "WaitForValidation", "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", "", false, "false", "False" ], [ "SleepInSeconds", "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", "", false, "false", "60" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the validation status from LCS", "Name": "Get-D365LcsAssetValidationStatus", "Links": [ null, null, null, null, null, null, null ], "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.", "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]" }, { "CommandName": "Get-D365LcsDatabaseBackups", "Description": "Get the available database backups from the Asset Library in LCS project", "Params": [ [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS\nDefault value can be configured using Set-D365LcsApiConfig", "", false, "false", "$Script:LcsApiProjectId" ], [ "BearerToken", "The token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "Latest", "Instruct the cmdlet to only fetch the latest file from the Azure Storage Account", "GetLatest", false, "false", "False" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get database backups from LCS project", "Name": "Get-D365LcsDatabaseBackups", "Links": [ null, null, null, null ], "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.", "Syntax": "Get-D365LcsDatabaseBackups [[-ProjectId] \u003cInt32\u003e] [[-BearerToken] \u003cString\u003e] [[-LcsApiUri] \u003cString\u003e] [-Latest] [[-RetryTimeout] \u003cTimeSpan\u003e] [-EnableException] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365LcsDatabaseOperationStatus", "Description": "Get the current status of a database operation against an environment from a LCS project", "Tags": [ "Environment", "Config", "Configuration", "LCS", "Database backup", "Api", "Backup", "Restore", "Refresh" ], "Params": [ [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS\nDefault value can be configured using Set-D365LcsApiConfig", "", false, "false", "$Script:LcsApiProjectId" ], [ "BearerToken", "The token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "OperationActivityId", "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", "ActivityId", true, "true (ByPropertyName)", "" ], [ "EnvironmentId", "The unique id of the environment that you want to work against\nThe Id can be located inside the LCS portal", "SourceEnvironmentId", true, "true (ByPropertyName)", "" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "WaitForCompletion", "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", "", false, "false", "False" ], [ "SleepInSeconds", "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", "", false, "false", "300" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the status of a database operation from LCS", "Name": "Get-D365LcsDatabaseOperationStatus", "Links": [ null, null, null, null, null, null, null ], "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.", "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]" }, { "CommandName": "Get-D365LcsDeploymentStatus", "Description": "Get the Deployment status for activity against an environment from the Dynamics LCS Portal", "Tags": [ "Environment", "Url", "Config", "Configuration", "LCS", "Upload", "Api", "AAD", "Token", "Deployment", "Deploy" ], "Params": [ [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS\nDefault value can be configured using Set-D365LcsApiConfig", "", false, "false", "$Script:LcsApiProjectId" ], [ "BearerToken", "The token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "ActivityId", "The unique id of the action that you started from the Invoke-D365LcsDeployment cmdlet", "ActionHistoryId", true, "true (ByPropertyName)", "" ], [ "EnvironmentId", "The unique id of the environment that you want to work against\nThe Id can be located inside the LCS portal", "", true, "false", "" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "WaitForCompletion", "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", "", false, "false", "False" ], [ "SleepInSeconds", "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", "", false, "false", "300" ], [ "FailOnErrorMessage", "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", "", false, "false", "False" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the Deployment status from LCS", "Name": "Get-D365LcsDeploymentStatus", "Links": [ null, null, null, null, null, null, null ], "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.", "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]" }, { "CommandName": "Get-D365LcsEnvironmentHistory", "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", "Params": [ [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS\nDefault value can be configured using Set-D365LcsApiConfig", "", false, "false", "$Script:LcsApiProjectId" ], [ "BearerToken", "The token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "EnvironmentId", "Id of the environment that you want to be working against", "", true, "false", "" ], [ "TraverseAllPages", "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", "", false, "false", "False" ], [ "FirstPages", "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", "", false, "false", "99" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "FailOnErrorMessage", "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", "", false, "false", "False" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get history for a given environment within a LCS project", "Name": "Get-D365LcsEnvironmentHistory", "Links": null, "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", "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]" }, { "CommandName": "Get-D365LcsEnvironmentMetadata", "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", "Params": [ [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS\nDefault value can be configured using Set-D365LcsApiConfig", "", false, "false", "$Script:LcsApiProjectId" ], [ "BearerToken", "The token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "EnvironmentId", "Id of the environment that you want to be working against", "", false, "false", "" ], [ "EnvironmentName", "Name of the environment that you want to be working against", "", false, "false", "" ], [ "TraverseAllPages", "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", "", false, "false", "False" ], [ "FirstPages", "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", "", false, "false", "99" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "FailOnErrorMessage", "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", "", false, "false", "False" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get LCS environment meta data from within a project", "Name": "Get-D365LcsEnvironmentMetadata", "Links": null, "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", "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]" }, { "CommandName": "Get-D365LcsEnvironmentRsatCertificate", "Description": "Download and persist the active rsat certificate from environments from within a LCS project", "Params": [ [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS\nDefault value can be configured using Set-D365LcsApiConfig", "", false, "false", "$Script:LcsApiProjectId" ], [ "BearerToken", "The token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "EnvironmentId", "Id of the environment that you want to be working against", "", true, "false", "" ], [ "OutputPath", "Path to where you want the certificate files to be saved\nThe default value is: \"c:\\temp\\d365fo.tools\\RsatCert\\\"", "", false, "false", "$(Join-Path $Script:DefaultTempPath \"RsatCert\")" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "FailOnErrorMessage", "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", "", false, "false", "False" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get LCS environment rsat certificate from within a project", "Name": "Get-D365LcsEnvironmentRsatCertificate", "Links": null, "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.", "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]" }, { "CommandName": "Get-D365LcsSharedAssetFile", "Description": "Get the information for the file assets from the shared asset library of LCS matching the search criteria", "Params": [ [ "ProjectId", "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.", "", false, "false", "$Script:LcsApiProjectId" ], [ "FileType", "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\"", "", false, "false", "SoftwareDeployablePackage" ], [ "AssetName", "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", "", false, "false", "*" ], [ "AssetVersion", "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", "", false, "false", "*" ], [ "AssetFilename", "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", "", false, "false", "*" ], [ "AssetDescription", "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", "", false, "false", "*" ], [ "AssetId", "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", "", false, "false", "*" ], [ "BearerToken", "The token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "Latest", "Instruct the cmdlet to only fetch the latest file from the Asset Library from LCS", "GetLatest", false, "false", "False" ], [ "SkipSasGeneration", "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", "", false, "false", "False" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Florian Hopfner (@FH-Inway)", "Synopsis": "Get information for assets from the shared asset library of LCS", "Name": "Get-D365LcsSharedAssetFile", "Links": [ null, null, null, null, null ], "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.", "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]" }, { "CommandName": "Get-D365MaintenanceMode", "Description": "Get the maintenance mode status of the Dynamics 365 environment to make sure that things are in the correct state", "Tags": [ "MaintenanceMode", "Maintenance", "License", "Configuration", "Servicing" ], "Params": [ [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ] ], "Alias": "", "Author": "Mötz Jensen (@splaxi)", "Synopsis": "Get the maintenance mode status of the environment", "Name": "Get-D365MaintenanceMode", "Links": [ null, null ], "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eGet-D365MaintenanceMode\nThis will get the current state of the maintenance mode of the environment", "Syntax": "Get-D365MaintenanceMode [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365Model", "Description": "Get available model from the machine running the AOS service for Dynamics 365 Finance \u0026 Operations", "Tags": [ "PackagesLocalDirectory", "Servicing", "Model", "Models", "Module", "Modules" ], "Params": [ [ "Name", "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", "", false, "false", "*" ], [ "Module", "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", "ModuleName", false, "true (ByPropertyName)", "*" ], [ "CustomizableOnly", "Instructs the cmdlet to filter out all models that cannot be customized", "", false, "false", "False" ], [ "ExcludeMicrosoftModels", "Instructs the cmdlet to exclude all models that has Microsoft as the publisher from the output", "", false, "false", "False" ], [ "ExcludeBinaryModels", "Instruct the cmdlet to exclude binary models from the output", "", false, "false", "False" ], [ "BinDir", "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", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get available model from Dynamics 365 Finance \u0026 Operations environment", "Name": "Get-D365Model", "Links": null, "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", "Syntax": "Get-D365Model [[-Name] \u003cString\u003e] [[-Module] \u003cString\u003e] [-CustomizableOnly] [-ExcludeMicrosoftModels] [-ExcludeBinaryModels] [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365Module", "Description": "Get installed package / module from the machine running the AOS service for Dynamics 365 Finance \u0026 Operations", "Tags": [ "PackagesLocalDirectory", "Servicing", "Model", "Models", "Package", "Packages" ], "Params": [ [ "Name", "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", "", false, "false", "*" ], [ "ExcludeBinaryModules", "Instruct the cmdlet to exclude binary modules from the output", "", false, "false", "False" ], [ "InDependencyOrder", "Instructs the cmdlet to return modules in dependency order, starting with modules\r\nwith no references to other modules.", "Dependency", false, "false", "False" ], [ "BinDir", "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", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get installed package / module from Dynamics 365 Finance \u0026 Operations environment", "Name": "Get-D365Module", "Links": null, "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...", "Syntax": "Get-D365Module [[-Name] \u003cString\u003e] [-ExcludeBinaryModules] [-InDependencyOrder] [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365OfflineAuthenticationAdminEmail", "Description": "Get the registered offline administrator from the \"DynamicsDevConfig.xml\" file located in the default Package Directory", "Tags": [ "Development", "Email", "DynamicsDevConfig", "Offline", "Authentication" ], "Params": [ ], "Alias": "", "Synopsis": "Gets the registered offline administrator e-mail configured", "Name": "Get-D365OfflineAuthenticationAdminEmail", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eGet-D365OfflineAuthenticationAdminEmail\nWill read the DynamicsDevConfig.xml and display the registered Offline Administrator E-mail address.", "Syntax": "Get-D365OfflineAuthenticationAdminEmail [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365PackageBundleDetail", "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", "Tags": [ "Hotfix", "KB", "Manifest", "HotfixPackageBundle", "axscdppkg", "Package", "Bundle", "Deployable" ], "Params": [ [ "Path", "Path to the axscdppkg file you want to analyze", "File", true, "false", "" ], [ "ExtractionPath", "Path where you want the cmdlet to work with extraction of all the files\nDefault value is: C:\\Users\\Username\\AppData\\Local\\Temp", "", false, "false", "([System.IO.Path]::GetTempPath())" ], [ "KB", "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", "", false, "false", "*" ], [ "Hotfix", "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", "", false, "false", "*" ], [ "Traverse", "Switch to instruct the cmdlet to traverse the inner packages and extract their details", "", false, "false", "False" ], [ "KeepFiles", "Switch to instruct the cmdlet to keep the files for further manual analyze", "", false, "false", "False" ], [ "IncludeRawManifest", "Switch to instruct the cmdlet to include the raw content of the manifest file\nOnly works with the -Traverse option", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the details from an axscdppkg file", "Name": "Get-D365PackageBundleDetail", "Links": null, "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.", "Syntax": "Get-D365PackageBundleDetail [-Path] \u003cString\u003e [[-ExtractionPath] \u003cString\u003e] [[-KB] \u003cString\u003e] [[-Hotfix] \u003cString\u003e] [-Traverse] [-KeepFiles] [-IncludeRawManifest] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365PackageLabelResourceFile", "Description": "Get label (resource) file from the package directory of a Dynamics 365 Finance \u0026 Operations environment", "Tags": [ "PackagesLocalDirectory", "Label", "Labels", "Language", "Development", "Servicing", "Module", "Package", "Packages" ], "Params": [ [ "PackageDirectory", "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", "Path", true, "true (ByPropertyName)", "" ], [ "Name", "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", "", false, "false", "*" ], [ "Language", "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", "", false, "false", "en-US" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get label / resource file from a package", "Name": "Get-D365PackageLabelResourceFile", "Links": null, "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", "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]" }, { "CommandName": "Get-D365PackageLabelResources", "Description": "Get label details from the resource file for a Dynamics 365 Finance \u0026 Operations environment", "Tags": [ "PackagesLocalDirectory", "Label", "Labels", "Language", "Development", "Servicing", "Resource", "Resources" ], "Params": [ [ "FilePath", "The path to resource file that you want to get label details from", "Path", true, "true (ByPropertyName)", "" ], [ "Name", "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", "", false, "false", "*" ], [ "Value", "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", "", false, "false", "*" ], [ "IncludePath", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get label from the resource file", "Name": "Get-D365PackageLabelResources", "Links": null, "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.", "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]" }, { "CommandName": "Get-D365ProductInformation", "Description": "Gets detailed information about application and platform", "Tags": [ "Build", "Version", "Reference", "ProductVersion", "ProductDetails", "Product" ], "Params": [ ], "Alias": "", "Author": "Rasmus Andersen (@ITRasmus)", "Synopsis": "Returns information about D365FO", "Name": "Get-D365ProductInformation", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eGet-D365ProductInformation\nThis will get product, platform and application version details for the environment", "Syntax": "Get-D365ProductInformation [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365RsatCertificateThumbprint", "Description": "Locate the thumbprint for the certificate created during the RSAT installation", "Tags": [ "RSAT", "Certificate", "Testing", "Regression Suite Automation Test", "Regression", "Test", "Automation." ], "Params": [ ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the thumbprint from the RSAT certificate", "Name": "Get-D365RsatCertificateThumbprint", "Links": null, "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.", "Syntax": "Get-D365RsatCertificateThumbprint [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365RsatPlaybackFile", "Description": "Get all the RSAT playback files from the last executions", "Tags": [ "RSAT", "Testing", "Regression Suite Automation Test", "Regression", "Test", "Automation", "Playback" ], "Params": [ [ "Path", "The path where the RSAT tool will be writing the files\nThe default path is:\r\n\"C:\\Users\\USERNAME\\AppData\\Roaming\\regressionTool\\playback\"", "", false, "false", "$Script:RsatplaybackPath" ], [ "Name", "Name of Test Case that you are looking for\nDefault value is \"*\" which will search for all Test Cases and their corresponding files", "", false, "false", "*" ], [ "ExecutionUsername", "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", "", false, "false", "" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the RSAT playback files", "Name": "Get-D365RsatPlaybackFile", "Links": null, "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.", "Syntax": "Get-D365RsatPlaybackFile [-Path \u003cString\u003e] [-Name \u003cString\u003e] [\u003cCommonParameters\u003e]\nGet-D365RsatPlaybackFile [-Name \u003cString\u003e] [-ExecutionUsername \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365RsatSoapHostname", "Description": "Get the SOAP hostname from the IIS configuration, to be used during the Rsat configuration", "Tags": [ "RSAT", "Testing", "Regression Suite Automation Test", "Regression", "Test", "Automation", "SOAP" ], "Params": [ ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the SOAP hostname for the D365FO environment", "Name": "Get-D365RsatSoapHostname", "Links": null, "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.", "Syntax": "Get-D365RsatSoapHostname [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365Runbook", "Description": "Get the full path and filename of a Dynamics 365 Runbook", "Tags": [ "Runbook", "Servicing", "Hotfix", "DeployablePackage", "Deployable Package", "InstallationRecordsDirectory", "Installation Records Directory" ], "Params": [ [ "Path", "Path to the folder containing the runbook files\nThe default path is \"InstallationRecord\" which is normally located on the \"C:\\DynamicsAX\\InstallationRecords\"", "", false, "true (ByValue, ByPropertyName)", "(Join-Path $Script:InstallationRecordsDir \"Runbooks\")" ], [ "Name", "Name of the runbook file that you are looking for\nThe parameter accepts wildcards. E.g. -Name *hotfix-20181024*", "", false, "false", "*" ], [ "Latest", "Instruct the cmdlet to only get the latest runbook file, based on the last written attribute", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get a Dynamics 365 Runbook", "Name": "Get-D365Runbook", "Links": null, "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.", "Syntax": "Get-D365Runbook [[-Path] \u003cString\u003e] [[-Name] \u003cString\u003e] [-Latest] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365RunbookId", "Description": "Get the runbook id from inside a runbook file", "Tags": [ "Runbook", "Analyze", "RunbookId", "Runbooks" ], "Params": [ [ "Path", "Path to the runbook file that you want to analyse\nAccepts value from pipeline, also by property", "File", true, "true (ByValue, ByPropertyName)", "" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get runbook id", "Name": "Get-D365RunbookId", "Links": null, "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.", "Syntax": "Get-D365RunbookId [-Path] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365RunbookLogFile", "Description": "Get the log files for a specific Runbook step", "Tags": [ "Runbook", "Servicing", "Hotfix", "DeployablePackage", "Deployable Package", "InstallationRecordsDirectory", "Installation Records Directory" ], "Params": [ [ "Path", "Path to Software Deployable Package that was run in connection with the runbook", "File", true, "true (ByValue, ByPropertyName)", "" ], [ "Step", "Step id for the step that you want to locate the log files for", "StepId", true, "true (ByValue, ByPropertyName)", "" ], [ "Latest", "Instruct the cmdlet to only work with the latest log file\nIs based on the last written attribute on the log file", "", false, "false", "False" ], [ "OpenInEditor", "Instruct the cmdlet to open the log file in the default text editor", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get log file from a Runbook step", "Name": "Get-D365RunbookLogFile", "Links": null, "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.", "Syntax": "Get-D365RunbookLogFile [-Path] \u003cString\u003e [-Step] \u003cString\u003e [-Latest] [-OpenInEditor] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365SDPCleanUp", "Description": "Gets the configured retention period before updates are deleted", "Tags": [ "CleanUp", "Retention", "Servicing", "Cut Off", "DeployablePackage", "Deployable Package" ], "Params": [ ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the cleanup retention period", "Name": "Get-D365SDPCleanUp", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eGet-D365SDPCleanUp\nThis will get the configured retention period from the registry", "Syntax": "Get-D365SDPCleanUp [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365SDPDetails", "Description": "Details details about the inner modules / packages that a Software Deployable Contains", "Params": [ [ "Path", "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", "File", true, "false", "" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get details from the Software Deployable Package", "Name": "Get-D365SDPDetails", "Links": null, "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", "Syntax": "Get-D365SDPDetails [-Path] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365Table", "Description": "Get a table either by TableName (wildcard search allowed) or by TableId", "Tags": [ "Table", "Tables", "AOT", "TableId", "Development" ], "Params": [ [ "Name", "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", "", false, "false", "*" ], [ "Id", "The specific id for the table you are looking for", "", true, "false", "0" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ] ], "Alias": "", "Author": "Mötz Jensen (@splaxi)", "Synopsis": "Get a table", "Name": "Get-D365Table", "Links": null, "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.", "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]" }, { "CommandName": "Get-D365TableField", "Description": "Get a field either by FieldName (wildcard search allowed) or by FieldId", "Tags": [ "Table", "Tables", "Fields", "TableField", "Table Field", "TableName", "TableId" ], "Params": [ [ "TableId", "The id of the table that the field belongs to", "", true, "true (ByPropertyName)", "0" ], [ "Name", "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", "", false, "false", "*" ], [ "FieldId", "Id of the field that you are looking for\nType is integer", "", false, "true (ByPropertyName)", "0" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "TableName", "Name of the table that the field belongs to\nSearch will only return the first hit (unordered) and work against that hit", "", true, "false", "" ], [ "IncludeTableDetails", "Switch options to enable the result set to include extended details", "", false, "false", "False" ], [ "SearchAcrossTables", "Switch options to force the cmdlet to search across all tables when looking for the field", "", true, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@splaxi)", "Synopsis": "Get a field from table", "Name": "Get-D365TableField", "Links": null, "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.", "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]" }, { "CommandName": "Get-D365TableSequence", "Description": "Get the sequence details for tables", "Tags": [ "Table", "RecId", "Sequence", "Record Id" ], "Params": [ [ "TableName", "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", "Name", false, "true (ByPropertyName)", "*" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the sequence object for table", "Name": "Get-D365TableSequence", "Links": null, "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.", "Syntax": "Get-D365TableSequence [[-TableName] \u003cString\u003e] [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365TablesInChangedTracking", "Description": "Get table(s) that is taking part of the SQL Server Change Tracking mechanism", "Tags": [ "Table", "Change Tracking", "Tablename", "DMF", "DIXF" ], "Params": [ [ "Name", "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", "", false, "false", "*" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ] ], "Alias": "", "Author": "Mötz Jensen (@splaxi)", "Synopsis": "Get table that is taking part of Change Tracking", "Name": "Get-D365TablesInChangedTracking", "Links": null, "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.", "Syntax": "Get-D365TablesInChangedTracking [[-Name] \u003cString\u003e] [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365TfsUri", "Description": "Gets the URI from the configuration of the local tfs connection in visual studio", "Tags": [ "TFS", "VSTS", "URL", "URI", "Servicing", "Development" ], "Params": [ [ "Path", "Path to the tf.exe file that the cmdlet will invoke", "", false, "false", "$Script:TfDir" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the TFS / VSTS registered URL / URI", "Name": "Get-D365TfsUri", "Links": null, "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.", "Syntax": "Get-D365TfsUri [[-Path] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365TfsWorkspace", "Description": "Gets the workspace path from the configuration of the local tfs in visual studio", "Tags": [ "TFS", "VSTS", "URL", "URI", "Servicing", "Development" ], "Params": [ [ "Path", "Path to the directory where the Team Foundation Client executable is located", "", false, "false", "$Script:TfDir" ], [ "TfsUri", "Uri to the TFS / VSTS that the workspace is connected to", "", false, "true (ByPropertyName)", "$Script:TfsUri" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the TFS / VSTS registered workspace path", "Name": "Get-D365TfsWorkspace", "Links": null, "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.", "Syntax": "Get-D365TfsWorkspace [[-Path] \u003cString\u003e] [[-TfsUri] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365Url", "Description": "Get the complete URL for accessing the Dynamics 365 Finance \u0026 Operations instance running on this machine", "Tags": [ "URL", "URI", "Servicing" ], "Params": [ [ "Force", "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.", "", false, "false", "False" ] ], "Alias": "", "Author": "Rasmus Andersen (@ITRasmus)", "Synopsis": "Get the url for accessing the instance", "Name": "Get-D365Url", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eGet-D365Url\nThis will get the correct URL to access the environment", "Syntax": "Get-D365Url [-Force] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365User", "Description": "Get all relevant user details from the Dynamics 365 for Finance \u0026 Operations", "Tags": [ "User", "Users" ], "Params": [ [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "Email", "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", "", false, "false", "*" ], [ "ExcludeSystemUsers", "Instructs the cmdlet to filter out all known system users", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get users from the environment", "Name": "Get-D365User", "Links": null, "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.", "Syntax": "Get-D365User [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [[-Email] \u003cString\u003e] [-ExcludeSystemUsers] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365UserAuthenticationDetail", "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", "Tags": [ "User", "Users", "Security", "Configuration", "Authentication" ], "Params": [ [ "Email", "The e-mail address / login name of the user that the cmdlet must gather details about", "", true, "true (ByValue)", "" ] ], "Alias": "", "Synopsis": "Cmdlet used to get authentication details about a user", "Name": "Get-D365UserAuthenticationDetail", "Links": null, "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\"", "Syntax": "Get-D365UserAuthenticationDetail [-Email] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365VisualStudioCompilerResult", "Description": "Get the Visual Studio compiler outputs presented in a structured manner on the screen", "Tags": [ "Compiler", "Build", "Errors", "Warnings", "Tasks" ], "Params": [ [ "Module", "Name of the module that you want to work against\nDefault value is \"*\" which will search for all modules", "ModuleName", false, "false", "*" ], [ "ErrorsOnly", "Instructs the cmdlet to only output compile results where there was errors detected", "", false, "false", "False" ], [ "OutputTotals", "Instructs the cmdlet to output the total errors and warnings after the analysis", "", false, "false", "False" ], [ "OutputAsObjects", "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", "", false, "false", "False" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get the compiler outputs presented", "Name": "Get-D365VisualStudioCompilerResult", "Links": null, "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", "Syntax": "Get-D365VisualStudioCompilerResult [[-Module] \u003cString\u003e] [-ErrorsOnly] [-OutputTotals] [-OutputAsObjects] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365WebServerType", "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.", "Params": [ ], "Alias": "", "Author": "Sander Holvoet (@smholvoet)", "Synopsis": "Get the default web server to be used", "Name": "Get-D365WebServerType", "Links": null, "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\".", "Syntax": "Get-D365WebServerType [\u003cCommonParameters\u003e]" }, { "CommandName": "Get-D365WindowsActivationStatus", "Description": "Get all the important license and activation information from the machine", "Tags": [ "Windows", "License", "Activation", "Arm", "Rearm" ], "Params": [ ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Get activation status", "Name": "Get-D365WindowsActivationStatus", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eGet-D365WindowsActivationStatus\nThis will get the remaining grace and rearm activation information for the machine", "Syntax": "Get-D365WindowsActivationStatus [\u003cCommonParameters\u003e]" }, { "CommandName": "Import-D365AadApplication", "Description": "Provides a method for importing a AAD application into D365FO.", "Tags": [ "User", "Users", "Security", "Configuration", "Permission", "AAD", "Azure Active Directory", "Group", "Groups" ], "Params": [ [ "Name", "The name that the imported application should have inside the D365FO environment", "", true, "false", "" ], [ "UserId", "The id of the user linked to the application inside the D365FO environment", "", true, "false", "" ], [ "ClientId", "The Client ID that the imported application should use inside the D365FO environment", "", true, "false", "" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ] ], "Alias": "", "Author": "Gert Van Der Heyden (@gertvdheyden)", "Synopsis": "Used to import Aad applications into D365FO", "Name": "Import-D365AadApplication", "Links": null, "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.", "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]" }, { "CommandName": "Import-D365AadUser", "Description": "Provides a method for importing a AAD UserGroup or a comma separated list of AadUsers into D365FO.", "Tags": [ "User", "Users", "Security", "Configuration", "Permission", "AAD", "Azure Active Directory", "Group", "Groups" ], "Params": [ [ "AadGroupName", "Azure Active directory user group containing users to be imported", "", true, "false", "" ], [ "Users", "Array of users that you want to import into the D365FO environment", "", true, "false", "" ], [ "StartupCompany", "Startup company of users imported.\nDefault is DAT", "", false, "false", "DAT" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "IdPrefix", "A text that will be prefixed into the ID field. E.g. -IdPrefix \"EXT-\" will import users and set ID starting with \"EXT-...\"", "", false, "false", "" ], [ "NameSuffix", "A text that will be suffixed into the NAME field. E.g. -NameSuffix \"(Contoso)\" will import users and append \"(Contoso)\"\" to the NAME", "", false, "false", "" ], [ "IdValue", "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", "", false, "false", "Login" ], [ "NameValue", "Specify which field to use as NAME value when importing the users.\r\nAvailable options \u0027FirstName\u0027 / \u0027DisplayName\u0027\nDefault is \u0027DisplayName\u0027", "", false, "false", "DisplayName" ], [ "AzureAdCredential", "Use a PSCredential object for connecting with AzureAd", "", false, "false", "" ], [ "SkipAzureAd", "Switch to instruct the cmdlet to skip validating against the Azure Active Directory", "", false, "false", "False" ], [ "ForceExactAadGroupName", "Force to find the exact name of the Azure Active Directory Group", "", false, "false", "False" ], [ "AadGroupId", "Azure Active directory user group ID containing users to be imported", "", true, "false", "" ], [ "EmailValue", "Specify which field to use as EMAIL value when importing the users.\r\nAvailable options \u0027Mail\u0027 / \u0027UserPrincipalName\u0027\nDefault is \u0027Mail\u0027", "", false, "false", "Mail" ], [ "TenantId", "The TenantId to use when connecting to Azure Active Directory\nUses the tenant id of the current environment if not specified.", "", false, "false", "$Script:TenantId" ] ], "Alias": "", "Author": "Rasmus Andersen (@ITRasmus)", "Synopsis": "Used to import Aad users into D365FO", "Name": "Import-D365AadUser", "Links": null, "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).", "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]" }, { "CommandName": "Import-D365Bacpac", "Description": "Import a bacpac file to either a Tier1 or Tier2 environment", "Tags": [ "Database", "Bacpac", "Tier1", "Tier2", "Golden Config", "Config", "Configuration" ], "Params": [ [ "ImportModeTier1", "Switch to instruct the cmdlet that it will import into a Tier1 environment\nThe cmdlet will expect to work against a SQL Server instance", "", true, "false", "False" ], [ "ImportModeTier2", "Switch to instruct the cmdlet that it will import into a Tier2 environment\nThe cmdlet will expect to work against an Azure DB instance", "", true, "false", "False" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "BacpacFile", "Path to the bacpac file you want to import into the database server", "File", true, "true (ByPropertyName)", "" ], [ "NewDatabaseName", "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", "", true, "false", "" ], [ "AxDeployExtUserPwd", "Password that is obtained from LCS", "", false, "false", "" ], [ "AxDbAdminPwd", "Password that is obtained from LCS", "", false, "false", "" ], [ "AxRuntimeUserPwd", "Password that is obtained from LCS", "", false, "false", "" ], [ "AxMrRuntimeUserPwd", "Password that is obtained from LCS", "", false, "false", "" ], [ "AxRetailRuntimeUserPwd", "Password that is obtained from LCS", "", false, "false", "" ], [ "AxRetailDataSyncUserPwd", "Password that is obtained from LCS", "", false, "false", "" ], [ "AxDbReadonlyUserPwd", "Password that is obtained from LCS", "", false, "false", "" ], [ "CustomSqlFile", "Path to the sql script file that you want the cmdlet to execute against your data after it has been imported", "", false, "false", "" ], [ "ModelFile", "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", "", false, "false", "" ], [ "DiagnosticFile", "Path to where you want the import to output a diagnostics file to assist you in troubleshooting the import", "", false, "false", "" ], [ "ImportOnly", "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", "", false, "false", "False" ], [ "MaxParallelism", "Sets SqlPackage.exe\u0027s degree of parallelism for concurrent operations running against a database\nThe default value is 8", "", false, "false", "8" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ImportBacpac\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ], [ "EnableException", "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", "", false, "false", "False" ], [ "Properties", "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.", "", false, "false", "" ] ], "Alias": "", "Author": "Rasmus Andersen (@ITRasmus)", "Synopsis": "Import a bacpac file", "Name": "Import-D365Bacpac", "Links": null, "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.", "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]" }, { "CommandName": "Import-D365Dacpac", "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", "Tags": [ "Database", "Dacpac", "Tier1", "Tier2", "Golden Config", "Config", "Configuration" ], "Params": [ [ "Path", "Path to the dacpac file that you want to import", "File,Dacpac", true, "false", "" ], [ "ModelFile", "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", "", false, "false", "" ], [ "PublishFile", "Path to the publish / profile file that contains extended parameters for the SqlPackage.exe assembly", "ProfileFile", false, "false", "" ], [ "DiagnosticFile", "Path to where you want the import to output a diagnostics file to assist you in troubleshooting the import", "", false, "false", "" ], [ "MaxParallelism", "Sets SqlPackage.exe\u0027s degree of parallelism for concurrent operations running against a database\nThe default value is 8", "", false, "false", "8" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ImportDacpac\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Import dacpac file to a database", "Name": "Import-D365Dacpac", "Links": null, "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.", "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]" }, { "CommandName": "Import-D365ExternalUser", "Description": "Imports an user from an AAD that is NOT the same as the AAD tenant that the D365FO environment is running under", "Tags": [ "User", "Users", "Security", "Configuration", "Permission", "AAD", "Azure Active Directory" ], "Params": [ [ "Id", "The internal Id that the user must be imported with\nThe Id has to unique across the entire user base", "", true, "false", "" ], [ "Name", "The display name of the user inside the D365FO environment", "", true, "false", "" ], [ "Email", "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", "", true, "false", "" ], [ "Enabled", "Should the imported user be enabled or not?\nDefault value is 1, which equals true / yes", "", false, "false", "1" ], [ "Company", "Default company that should be configured for the user, for when they sign-in to the D365 environment\nDefault value is \"DAT\"", "", false, "false", "DAT" ], [ "Language", "Language that should be configured for the user, for when they sign-in to the D365 environment\nDefault value is \"en-US\"", "", false, "false", "en-us" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ] ], "Alias": "", "Author": "Anderson Joyle (@AndersonJoyle)", "Synopsis": "Import an user from an external Azure Active Directory (AAD)", "Name": "Import-D365ExternalUser", "Links": null, "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\".", "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]" }, { "CommandName": "Import-D365Model", "Description": "Import a model into a Dynamics 365 for Finance \u0026 Operations environment", "Tags": [ "ModelUtil", "Axmodel", "Model", "Import", "Replace", "Source Control", "Vsts", "Azure DevOps" ], "Params": [ [ "Path", "Path to the axmodel file that you want to import", "File", true, "false", "" ], [ "BinDir", "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", "", false, "false", "\"$Script:PackageDirectory\\bin\"" ], [ "MetaDataDir", "The path to the meta data directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "\"$Script:MetaDataDir\"" ], [ "Replace", "Instruct the cmdlet to replace an already existing model", "", false, "false", "False" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModelUtilImport\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Import a model into Dynamics 365 for Finance \u0026 Operations", "Name": "Import-D365Model", "Links": null, "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.", "Syntax": "Import-D365Model [-Path] \u003cString\u003e [[-BinDir] \u003cString\u003e] [[-MetaDataDir] \u003cString\u003e] [-Replace] [-LogPath \u003cString\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [\u003cCommonParameters\u003e]" }, { "CommandName": "Import-D365RsatSelfServiceCertificates", "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", "Params": [ [ "Path", "Path to the folder where the .cer and .pxf files are located\nThe files needs to be extracted from the zip archive", "", true, "true (ByPropertyName)", "" ], [ "Password", "Password for the .pxf file\nWorking with self-service environments, the password will be displayed during the download of the zip archive", "", true, "true (ByPropertyName)", "" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Import certificates for RSAT", "Name": "Import-D365RsatSelfServiceCertificates", "Links": null, "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", "Syntax": "Import-D365RsatSelfServiceCertificates [-Path] \u003cString\u003e [-Password] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Initialize-D365RsatCertificate", "Description": "Creates a new self signed certificate for automated testing and reconfigures the AOS Windows Identity Foundation configuration to trust the certificate", "Tags": [ "Automated Test", "Test", "Regression", "Certificate", "Thumbprint" ], "Params": [ [ "CertificateFileName", "Filename to be used when exporting the cer file", "", false, "false", "(Join-Path $env:TEMP \"TestAuthCert.cer\")" ], [ "PrivateKeyFileName", "Filename to be used when exporting the pfx file", "", false, "false", "(Join-Path $env:TEMP \"TestAuthCert.pfx\")" ], [ "Password", "The password that you want to use to protect your certificate with\nThe default value is: \"Password1\"", "", false, "false", "(ConvertTo-SecureString -String \"Password1\" -Force -AsPlainText)" ], [ "CertificateOnly", "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", "", false, "false", "False" ], [ "KeepCertificateFile", "Instruct the cmdlet to copy the certificate file from the working directory into the desired location specified with OutputPath parameter", "", false, "false", "False" ], [ "OutputPath", "Path to where you want the certificate file exported to, when using the KeepCertificateFile parameter switch\nDefault value is: \"c:\\temp\\d365fo.tools\"", "", false, "false", "$Script:DefaultTempPath" ] ], "Alias": "Initialize-D365TestAutomationCertificate", "Author": "Kenny Saelen (@kennysaelen)", "Synopsis": "Create and configure test automation certificate", "Name": "Initialize-D365RsatCertificate", "Links": null, "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.", "Syntax": "Initialize-D365RsatCertificate [-CertificateFileName \u003cString\u003e] [-PrivateKeyFileName \u003cString\u003e] [-Password \u003cSecureString\u003e] [-CertificateOnly] [-KeepCertificateFile] [-OutputPath \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Install-D365SupportingSoftware", "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", "Params": [ [ "Name", "The name of the software to install\nSupport a list of softwares that you want to have installed on the system", "SoftwareName", true, "false", "" ], [ "Force", "Instruct the cmdlet to install the latest version of the software, regardless if it is already present on the system", "", false, "false", "False" ] ], "Alias": "", "Author": "Dag Calafell (@dodiggitydag)", "Synopsis": "Install software supporting F\u0026O development", "Name": "Install-D365SupportingSoftware", "Links": null, "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.", "Syntax": "Install-D365SupportingSoftware [-Name] \u003cString[]\u003e [-Force] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365AzCopyTransfer", "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", "Tags": [ "Azure", "Azure Storage", "Config", "Configuration", "Token", "Blob", "File", "Files", "Latest", "Bacpac", "Container", "LCS", "Asset", "Library" ], "Params": [ [ "SourceUri", "Source file uri that you want to transfer", "FileLocation,SourceUrl", true, "true (ByPropertyName)", "" ], [ "DestinationUri", "Destination file uri that you want to transfer the file to", "DestinationFile", true, "false", "" ], [ "FileName", "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", "", false, "true (ByPropertyName)", "" ], [ "DeleteOnTransferComplete", "Instruct the cmdlet to delete the source file when done transfering\nDefault is $false which will leave the source file", "", false, "false", "False" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\AzCopy\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ], [ "Force", "Instruct the cmdlet to overwrite already existing file", "", false, "false", "False" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Transfer a file using AzCopy", "Name": "Invoke-D365AzCopyTransfer", "Links": null, "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.", "Syntax": "Invoke-D365AzCopyTransfer [-SourceUri] \u003cString\u003e [-DestinationUri] \u003cString\u003e [[-FileName] \u003cString\u003e] [-DeleteOnTransferComplete] [[-LogPath] \u003cString\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [-Force] [-EnableException] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365AzureDevOpsNugetPush", "Description": "Push a package / nuget to an Azure DevOps feed", "Params": [ [ "Path", "Path to the package / nuget that you want to push to the Azure DevOps feed", "PackagePath", false, "false", "" ], [ "Source", "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", "NugetSource,Destination", false, "false", "" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\Nuget\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Push a package / nuget to Azure DevOps", "Name": "Invoke-D365AzureDevOpsNugetPush", "Links": null, "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.", "Syntax": "Invoke-D365AzureDevOpsNugetPush [[-Path] \u003cString\u003e] [[-Source] \u003cString\u003e] [[-LogPath] \u003cString\u003e] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365AzureStorageDownload", "Description": "Download any file to an Azure Storage Account", "Tags": [ "Azure", "Azure Storage", "Config", "Configuration", "Token", "Blob", "File", "Files", "Latest", "Bacpac", "Container" ], "Params": [ [ "AccountId", "Storage Account Name / Storage Account Id where you want to fetch the file from", "", false, "false", "$Script:AzureStorageAccountId" ], [ "AccessToken", "The token that has the needed permissions for the download action", "", false, "false", "$Script:AzureStorageAccessToken" ], [ "SAS", "The SAS key that you have created for the storage account or blob container", "", false, "false", "$Script:AzureStorageSAS" ], [ "Container", "Name of the blob container inside the storage account you where the file is", "Blobname,Blob", false, "false", "$Script:AzureStorageContainer" ], [ "FileName", "Name of the file that you want to download", "Name", true, "true (ByPropertyName)", "" ], [ "Path", "Path to the folder / location you want to save the file\nThe default path is \"c:\\temp\\d365fo.tools\"", "", false, "false", "$Script:DefaultTempPath" ], [ "Latest", "Instruct the cmdlet to download the latest file from Azure regardless of name", "GetLatest", true, "false", "False" ], [ "Force", "Instruct the cmdlet to overwrite the local file if it already exists", "", false, "false", "False" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Download a file to Azure", "Name": "Invoke-D365AzureStorageDownload", "Links": null, "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.", "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]" }, { "CommandName": "Invoke-D365AzureStorageUpload", "Description": "Upload any file to an Azure Storage Account", "Tags": [ "Azure", "Azure Storage", "Config", "Configuration", "Token", "Blob", "File", "Files", "Bacpac", "Container" ], "Params": [ [ "AccountId", "Storage Account Name / Storage Account Id where you want to store the file", "", false, "false", "$Script:AzureStorageAccountId" ], [ "AccessToken", "The token that has the needed permissions for the upload action", "", false, "false", "$Script:AzureStorageAccessToken" ], [ "SAS", "The SAS key that you have created for the storage account or blob container", "", false, "false", "$Script:AzureStorageSAS" ], [ "Container", "Name of the blob container inside the storage account you want to store the file", "Blobname,Blob", false, "false", "$Script:AzureStorageContainer" ], [ "Filepath", "Path to the file you want to upload", "Path,File", true, "true (ByValue)", "" ], [ "ContentType", "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", "", false, "false", "" ], [ "Force", "Instruct the cmdlet to overwrite the file in the container if it already exists", "", false, "false", "False" ], [ "DeleteOnUpload", "Switch to tell the cmdlet if you want the local file to be deleted after the upload completes", "", false, "false", "False" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Upload a file to Azure", "Name": "Invoke-D365AzureStorageUpload", "Links": null, "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.", "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]" }, { "CommandName": "Invoke-D365BestPractice", "Description": "Run the Best Practice checks against modules and models", "Tags": [ "Best Practice", "BP", "BPs", "Module", "Model", "Quality" ], "Params": [ [ "Module", "Name of the Module to analyse", "ModuleName", true, "true (ByPropertyName)", "" ], [ "Model", "Name of the Model to analyse", "ModelName", true, "true (ByPropertyName)", "" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the AOS service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:PackageDirectory\\bin\"" ], [ "MetaDataDir", "The path to the meta data directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "\"$Script:MetaDataDir\"" ], [ "PackagesRoot", "Instructs the cmdlet to use binary metadata", "", false, "false", "False" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\BestPractice\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "RunFixers", "Instructs the cmdlet to invoke the fixers for the identified warnings", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Gert Van Der Heyden (@gertvdheyden)", "Synopsis": "Run the Best Practice", "Name": "Invoke-D365BestPractice", "Links": null, "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.", "Syntax": "Invoke-D365BestPractice [-Module] \u003cString\u003e [-Model] \u003cString\u003e [[-BinDir] \u003cString\u003e] [[-MetaDataDir] \u003cString\u003e] [-PackagesRoot] [[-LogPath] \u003cString\u003e] [-ShowOriginalProgress] [-RunFixers] [-OutputCommandOnly] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365CompilerResultAnalyzer", "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", "Tags": [ "Compiler", "Build", "Errors", "Warnings", "Tasks" ], "Params": [ [ "Path", "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", "LogFile", true, "true (ByValue, ByPropertyName)", "" ], [ "OutputPath", "Path where you want the excel file (xlsx-file) saved to", "", false, "false", "$Script:DefaultTempPath" ], [ "SkipWarnings", "Instructs the cmdlet to skip warnings while analyzing the compiler output log file", "", false, "false", "False" ], [ "SkipTasks", "Instructs the cmdlet to skip tasks while analyzing the compiler output log file", "", false, "false", "False" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Analyze the compiler output log", "Name": "Invoke-D365CompilerResultAnalyzer", "Links": null, "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", "Syntax": "Invoke-D365CompilerResultAnalyzer [-Path] \u003cString\u003e [[-OutputPath] \u003cString\u003e] [-SkipWarnings] [-SkipTasks] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365DataFlush", "Description": "Invoke one of the runnable classes that is clearing cache, data or something else", "Tags": [ "Flush", "Url", "Servicing" ], "Params": [ [ "Url", "URL to the Dynamics 365 instance you want to clear the AOD cache on", "", false, "false", "" ], [ "Class", "The class that you want to execute.\nDefault value is \"SysFlushAod\"", "", false, "false", "SysFlushAod" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Invoke the one of the data flush classes", "Name": "Invoke-D365DataFlush", "Links": null, "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.", "Syntax": "Invoke-D365DataFlush [[-Url] \u003cString\u003e] [-Class \u003cString[]\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365DbSync", "Description": "Uses the sync.exe (engine) to synchronize the database for the environment", "Tags": [ "Database", "Sync", "SyncDB", "Synchronization", "Servicing" ], "Params": [ [ "BinDirTools", "Path to where the tools on the machine can be found\nDefault value is normally the AOS Service PackagesLocalDirectory\\bin", "", false, "false", "$Script:BinDirTools" ], [ "MetadataDir", "Path to where the tools on the machine can be found\nDefault value is normally the AOS Service PackagesLocalDirectory", "", false, "false", "$Script:MetaDataDir" ], [ "SyncMode", "The sync mode the sync engine will use\nDefault value is: \"FullAll\"", "", false, "false", "FullAll" ], [ "Verbosity", "Parameter used to instruct the level of verbosity the sync engine has to report back\nDefault value is: \"Normal\"", "", false, "false", "Normal" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\DbSync\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Rasmus Andersen (@ITRasmus)", "Synopsis": "Invoke the synchronization process used in Visual Studio", "Name": "Invoke-D365DbSync", "Links": null, "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.", "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]" }, { "CommandName": "Invoke-D365DbSyncModule", "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", "Tags": [ "Database", "Sync", "SyncDB", "Synchronization", "Servicing" ], "Params": [ [ "Module", "Name of the model you want to sync tables and table extensions\nSupports an array of module names", "ModuleName", true, "true (ByValue, ByPropertyName)", "" ], [ "Verbosity", "Parameter used to instruct the level of verbosity the sync engine has to report back\nDefault value is: \"Normal\"", "", false, "false", "Normal" ], [ "BinDirTools", "Path to where the tools on the machine can be found\nDefault value is normally the AOS Service PackagesLocalDirectory\\bin", "", false, "false", "$Script:BinDirTools" ], [ "MetadataDir", "Path to where the tools on the machine can be found\nDefault value is normally the AOS Service PackagesLocalDirectory", "", false, "false", "$Script:MetaDataDir" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "LogPath", "The path where the log file will be saved", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\DbSync\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Jasper Callens - Cegeka", "Synopsis": "Synchronize all sync base and extension elements based on a modulename", "Name": "Invoke-D365DbSyncModule", "Links": null, "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.", "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]" }, { "CommandName": "Invoke-D365DbSyncPartial", "Description": "Uses the sync.exe (engine) to synchronize the database for the environment", "Tags": [ "Database", "Sync", "SyncDB", "Synchronization", "Servicing" ], "Params": [ [ "SyncList", "The list of objects that you want to pass on to the database synchronoziation engine", "", false, "false", "" ], [ "SyncExtensionsList", "The list of extension objects that you want to pass on to the database synchronoziation engine", "", false, "false", "" ], [ "SyncMode", "The sync mode the sync engine will use\nDefault value is: \"PartialList\"", "", false, "false", "PartialList" ], [ "Verbosity", "Parameter used to instruct the level of verbosity the sync engine has to report back\nDefault value is: \"Normal\"", "", false, "false", "Normal" ], [ "BinDirTools", "Path to where the tools on the machine can be found\nDefault value is normally the AOS Service PackagesLocalDirectory\\bin", "", false, "false", "$Script:BinDirTools" ], [ "MetadataDir", "Path to where the tools on the machine can be found\nDefault value is normally the AOS Service PackagesLocalDirectory", "", false, "false", "$Script:MetaDataDir" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\DbSync\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Invoke the synchronization process used in Visual Studio", "Name": "Invoke-D365DbSyncPartial", "Links": null, "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.", "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]" }, { "CommandName": "Invoke-D365GenerateReportAggregateDataEntity", "Description": "Traverse the Dynamics 365 Finance \u0026 Operations code repository for all Aggregate Data Entities and generate a metadata report", "Tags": [ "Metadata", "Report", "Documentation" ], "Params": [ [ "OutputPath", "Path to where you want the report file to be saved\nThe default value is: \"c:\\temp\\d365fo.tools\\\"", "", false, "false", "$Script:DefaultTempPath" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Generate Report for Aggregate Data Entity", "Name": "Invoke-D365GenerateReportAggregateDataEntity", "Links": null, "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\\\"", "Syntax": "Invoke-D365GenerateReportAggregateDataEntity [[-OutputPath] \u003cString\u003e] [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365GenerateReportAggregateMeasure", "Description": "Traverse the Dynamics 365 Finance \u0026 Operations code repository for all Aggregate Measures and generate a metadata report", "Tags": [ "Metadata", "Report", "Documentation" ], "Params": [ [ "OutputPath", "Path to where you want the report file to be saved\nThe default value is: \"c:\\temp\\d365fo.tools\\\"", "", false, "false", "$Script:DefaultTempPath" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Generate Report for Aggregate Measure", "Name": "Invoke-D365GenerateReportAggregateMeasure", "Links": null, "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\\\"", "Syntax": "Invoke-D365GenerateReportAggregateMeasure [[-OutputPath] \u003cString\u003e] [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365GenerateReportConfigKey", "Description": "Traverse the Dynamics 365 Finance \u0026 Operations code repository for all Config Keys and generate a metadata report", "Tags": [ "Metadata", "Report", "Documentation" ], "Params": [ [ "OutputPath", "Path to where you want the report file to be saved\nThe default value is: \"c:\\temp\\d365fo.tools\\\"", "", false, "false", "$Script:DefaultTempPath" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Generate Report for Config Key", "Name": "Invoke-D365GenerateReportConfigKey", "Links": null, "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\\\"", "Syntax": "Invoke-D365GenerateReportConfigKey [[-OutputPath] \u003cString\u003e] [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365GenerateReportConfigKeyGroup", "Description": "Traverse the Dynamics 365 Finance \u0026 Operations code repository for all Config Key Groups and generate a metadata report", "Tags": [ "Metadata", "Report", "Documentation" ], "Params": [ [ "OutputPath", "Path to where you want the report file to be saved\nThe default value is: \"c:\\temp\\d365fo.tools\\\"", "", false, "false", "$Script:DefaultTempPath" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Generate Report for Config Key Group", "Name": "Invoke-D365GenerateReportConfigKeyGroup", "Links": null, "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\\\"", "Syntax": "Invoke-D365GenerateReportConfigKeyGroup [[-OutputPath] \u003cString\u003e] [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365GenerateReportDataEntity", "Description": "Traverse the Dynamics 365 Finance \u0026 Operations code repository for all Data Entities and generate a metadata report", "Tags": [ "Metadata", "Report", "Documentation" ], "Params": [ [ "OutputPath", "Path to where you want the report file to be saved\nThe default value is: \"c:\\temp\\d365fo.tools\\\"", "", false, "false", "$Script:DefaultTempPath" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Generate Report for Data Entity", "Name": "Invoke-D365GenerateReportDataEntity", "Links": null, "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\\\"", "Syntax": "Invoke-D365GenerateReportDataEntity [[-OutputPath] \u003cString\u003e] [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365GenerateReportDataEntityField", "Description": "Traverse the Dynamics 365 Finance \u0026 Operations code repository for all Data Entities with their fields and generate a metadata report", "Tags": [ "Metadata", "Report", "Documentation" ], "Params": [ [ "OutputPath", "Path to where you want the report file to be saved\nThe default value is: \"c:\\temp\\d365fo.tools\\\"", "", false, "false", "$Script:DefaultTempPath" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Generate Report for Data Entity with fields", "Name": "Invoke-D365GenerateReportDataEntityField", "Links": null, "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\\\"", "Syntax": "Invoke-D365GenerateReportDataEntityField [[-OutputPath] \u003cString\u003e] [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365GenerateReportKpi", "Description": "Traverse the Dynamics 365 Finance \u0026 Operations code repository for all KPIs and generate a metadata report", "Tags": [ "Metadata", "Report", "Documentation" ], "Params": [ [ "OutputPath", "Path to where you want the report file to be saved\nThe default value is: \"c:\\temp\\d365fo.tools\\\"", "", false, "false", "$Script:DefaultTempPath" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Generate Report for KPI", "Name": "Invoke-D365GenerateReportKpi", "Links": null, "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\\\"", "Syntax": "Invoke-D365GenerateReportKpi [[-OutputPath] \u003cString\u003e] [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365GenerateReportLicenseCode", "Description": "Traverse the Dynamics 365 Finance \u0026 Operations code repository for all License Codes and generate a metadata report", "Tags": [ "Metadata", "Report", "Documentation" ], "Params": [ [ "OutputPath", "Path to where you want the report file to be saved\nThe default value is: \"c:\\temp\\d365fo.tools\\\"", "", false, "false", "$Script:DefaultTempPath" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Generate Report for License Code", "Name": "Invoke-D365GenerateReportLicenseCode", "Links": null, "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\\\"", "Syntax": "Invoke-D365GenerateReportLicenseCode [[-OutputPath] \u003cString\u003e] [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365GenerateReportMenuItem", "Description": "Traverse the Dynamics 365 Finance \u0026 Operations code repository for all types of Menu Items and generate a metadata report", "Tags": [ "Metadata", "Report", "Documentation" ], "Params": [ [ "OutputPath", "Path to where you want the report file to be saved\nThe default value is: \"c:\\temp\\d365fo.tools\\\"", "", false, "false", "$Script:DefaultTempPath" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Generate Report for Menu Item", "Name": "Invoke-D365GenerateReportMenuItem", "Links": null, "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\\\"", "Syntax": "Invoke-D365GenerateReportMenuItem [[-OutputPath] \u003cString\u003e] [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365GenerateReports", "Description": "Traverse the Dynamics 365 Finance \u0026 Operations code repository for all related objects and generate a metadata report for each", "Tags": [ "Metadata", "Report", "Documentation" ], "Params": [ [ "OutputPath", "Path to where you want the report file to be saved\nThe default value is: \"c:\\temp\\d365fo.tools\\\"", "", false, "false", "$Script:DefaultTempPath" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Generate Report for all related objects", "Name": "Invoke-D365GenerateReports", "Links": null, "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\\\"", "Syntax": "Invoke-D365GenerateReports [[-OutputPath] \u003cString\u003e] [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365GenerateReportSsrs", "Description": "Traverse the Dynamics 365 Finance \u0026 Operations code repository for all SSRS Reports and generate a metadata report", "Tags": [ "Metadata", "Report", "Documentation" ], "Params": [ [ "OutputPath", "Path to where you want the report file to be saved\nThe default value is: \"c:\\temp\\d365fo.tools\\\"", "", false, "false", "$Script:DefaultTempPath" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Generate Report for SSRS Report", "Name": "Invoke-D365GenerateReportSsrs", "Links": null, "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\\\"", "Syntax": "Invoke-D365GenerateReportSsrs [[-OutputPath] \u003cString\u003e] [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365GenerateReportTable", "Description": "Traverse the Dynamics 365 Finance \u0026 Operations code repository for all Tables and generate a metadata report", "Tags": [ "Metadata", "Report", "Documentation" ], "Params": [ [ "OutputPath", "Path to where you want the report file to be saved\nThe default value is: \"c:\\temp\\d365fo.tools\\\"", "", false, "false", "$Script:DefaultTempPath" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Generate Report for Table", "Name": "Invoke-D365GenerateReportTable", "Links": null, "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\\\"", "Syntax": "Invoke-D365GenerateReportTable [[-OutputPath] \u003cString\u003e] [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365GenerateReportWorkflowType", "Description": "Traverse the Dynamics 365 Finance \u0026 Operations code repository for all Workflow Types and generate a metadata report", "Tags": [ "Metadata", "Report", "Documentation" ], "Params": [ [ "OutputPath", "Path to where you want the report file to be saved\nThe default value is: \"c:\\temp\\d365fo.tools\\\"", "", false, "false", "$Script:DefaultTempPath" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\\bin\"" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Generate Report for Workflow Type", "Name": "Invoke-D365GenerateReportWorkflowType", "Links": null, "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\\\"", "Syntax": "Invoke-D365GenerateReportWorkflowType [[-OutputPath] \u003cString\u003e] [[-BinDir] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365InstallAzCopy", "Description": "Download and extract the AzCopy.exe to your machine", "Params": [ [ "Url", "Url/Uri to where the latest AzCopy download is located\nThe default value is for v10 as of writing", "", false, "false", "https://aka.ms/downloadazcopy-v10-windows" ], [ "Path", "Path to where you want the AzCopy to be extracted to\nDefault value is: \"C:\\temp\\d365fo.tools\\AzCopy\\AzCopy.exe\"", "", false, "false", "C:\\temp\\d365fo.tools\\AzCopy\\AzCopy.exe" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Download AzCopy.exe to your machine", "Name": "Invoke-D365InstallAzCopy", "Links": null, "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", "Syntax": "Invoke-D365InstallAzCopy [[-Url] \u003cString\u003e] [[-Path] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365InstallLicense", "Description": "Install a license for a 3. party solution using the builtin \"Microsoft.Dynamics.AX.Deployment.Setup.exe\" executable", "Tags": [ "License", "Install", "ISV", "3. Party", "Servicing" ], "Params": [ [ "Path", "Path to the license file", "File", true, "false", "" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "MetaDataDir", "The path to the meta data directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "\"$Script:MetaDataDir\"" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\"" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\InstallLicense\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@splaxi)", "Synopsis": "Install a license for a 3. party solution", "Name": "Invoke-D365InstallLicense", "Links": null, "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.", "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]" }, { "CommandName": "Invoke-D365InstallNuget", "Description": "Download the nuget.exe to your machine\n\nBy default it will download the latest version", "Params": [ [ "Path", "Path to where you want the nuget.exe to be downloaded to\nDefault value is: \"C:\\temp\\d365fo.tools\\nuget\\nuget.exe\"", "", false, "false", "C:\\temp\\d365fo.tools\\nuget" ], [ "Url", "Url/Uri to where the latest nuget download is located\nThe default value is \"https://dist.nuget.org/win-x86-commandline/latest/nuget.exe\"", "", false, "false", "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Download nuget.exe to your machine", "Name": "Invoke-D365InstallNuget", "Links": null, "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\".", "Syntax": "Invoke-D365InstallNuget [[-Path] \u003cString\u003e] [[-Url] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365InstallSqlPackage", "Description": "Download and extract SqlPackage.exe to your machine.", "Params": [ [ "Path", "Path to where you want the SqlPackage to be extracted to\nDefault value is: \"C:\\temp\\d365fo.tools\\SqlPackage\\SqlPackage.exe\"", "", false, "false", "C:\\temp\\d365fo.tools\\SqlPackage" ], [ "Latest", "Overrides the Url parameter and uses the latest download URL provided by the evergreen link https://aka.ms/sqlpackage-windows", "", false, "false", "False" ], [ "Url", "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", "", false, "false", "https://go.microsoft.com/fwlink/?linkid=2261576" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Download SqlPackage.exe to your machine", "Name": "Invoke-D365InstallSqlPackage", "Links": null, "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.", "Syntax": "Invoke-D365InstallSqlPackage [-Path \u003cString\u003e] [-Url \u003cString\u003e] [\u003cCommonParameters\u003e]\nInvoke-D365InstallSqlPackage [-Path \u003cString\u003e] [-Latest] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365LcsApiRefreshToken", "Description": "Invoke the refresh logic that refreshes the token object based on the ClientId and RefreshToken", "Tags": [ "LCS", "API", "Token", "BearerToken" ], "Params": [ [ "ClientId", "The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal", "", true, "false", "" ], [ "RefreshToken", "The Refresh Token that you want to use for the authentication process", "Token,refresh_token", true, "true (ByPropertyName)", "" ], [ "InputObject", "The entire object that you received from the Get-D365LcsApiToken command, which contains the needed RefreshToken", "", false, "false", "" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Refresh the token for lcs communication", "Name": "Invoke-D365LcsApiRefreshToken", "Links": [ null, null, null, null, null, null, null ], "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.", "Syntax": "Invoke-D365LcsApiRefreshToken -ClientId \u003cString\u003e [-InputObject \u003cPSObject\u003e] [-EnableException] [\u003cCommonParameters\u003e]\nInvoke-D365LcsApiRefreshToken -ClientId \u003cString\u003e -RefreshToken \u003cString\u003e [-EnableException] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365LcsDatabaseExport", "Description": "Start a database export from an environment from a LCS project", "Tags": [ "Environment", "Config", "Configuration", "LCS", "Database backup", "Api", "Backup", "Bacpac" ], "Params": [ [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS\nDefault value can be configured using Set-D365LcsApiConfig", "", false, "false", "$Script:LcsApiProjectId" ], [ "BearerToken", "The token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "SourceEnvironmentId", "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", "", true, "false", "" ], [ "BackupName", "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", "", true, "false", "" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "SkipInitialStatusFetch", "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.", "", false, "false", "False" ], [ "FailOnErrorMessage", "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", "", false, "false", "False" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Start a database export from an environment", "Name": "Invoke-D365LcsDatabaseExport", "Links": [ null, null, null, null, null, null, null, null ], "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.", "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]" }, { "CommandName": "Invoke-D365LcsDatabaseRefresh", "Description": "Start a database refresh between 2 environments from a LCS project", "Tags": [ "Environment", "Config", "Configuration", "LCS", "Database backup", "Api", "Backup", "Restore", "Refresh" ], "Params": [ [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS\nDefault value can be configured using Set-D365LcsApiConfig", "", false, "false", "$Script:LcsApiProjectId" ], [ "BearerToken", "The token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "SourceEnvironmentId", "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", "", true, "false", "" ], [ "TargetEnvironmentId", "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", "", true, "false", "" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "SkipInitialStatusFetch", "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.", "", false, "false", "False" ], [ "FailOnErrorMessage", "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", "", false, "false", "False" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Start a database refresh between 2 environments", "Name": "Invoke-D365LcsDatabaseRefresh", "Links": [ null, null, null, null, null, null, null ], "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.", "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]" }, { "CommandName": "Invoke-D365LcsDeployment", "Description": "Deploy a deployable package from the Asset Library from a LCS project using the API provided by Microsoft", "Tags": [ "Environment", "Url", "Config", "Configuration", "LCS", "Upload", "Api", "AAD", "Token", "Deployment", "Deploy" ], "Params": [ [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS\nDefault value can be configured using Set-D365LcsApiConfig", "", false, "false", "$Script:LcsApiProjectId" ], [ "AssetId", "The unique id of the asset / file that you are trying to deploy from LCS", "", true, "true (ByPropertyName)", "" ], [ "EnvironmentId", "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", "", true, "false", "" ], [ "UpdateName", "Name of the update when you are working against Self-Service environments", "", true, "false", "" ], [ "BearerToken", "The token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "FailOnErrorMessage", "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", "", false, "false", "False" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Start the deployment of a deployable package", "Name": "Invoke-D365LcsDeployment", "Links": [ null, null, null, null, null, null, null ], "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.", "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]" }, { "CommandName": "Invoke-D365LcsEnvironmentStart", "Description": "Start a specified IAAS environment that is Customer Managed through the LCS API.", "Tags": [ "Environment", "Start", "StartStop", "Stop", "LCS", "Api" ], "Params": [ [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS\nDefault value can be configured using Set-D365LcsApiConfig", "", false, "false", "$Script:LcsApiProjectId" ], [ "BearerToken", "The token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "EnvironmentId", "The unique id of the environment that you want to take action upon\nThe Id can be located inside the LCS portal", "", true, "false", "" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "FailOnErrorMessage", "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", "", false, "false", "False" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi), Billy Richardson (@richardsondev)", "Synopsis": "Start a specified environment through LCS.", "Name": "Invoke-D365LcsEnvironmentStart", "Links": [ null, null, null, null, null ], "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.", "Syntax": "Invoke-D365LcsEnvironmentStart [[-ProjectId] \u003cInt32\u003e] [[-BearerToken] \u003cString\u003e] [-EnvironmentId] \u003cString\u003e [[-LcsApiUri] \u003cString\u003e] [-FailOnErrorMessage] [[-RetryTimeout] \u003cTimeSpan\u003e] [-EnableException] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365LcsEnvironmentStop", "Description": "Stop a specified IAAS environment that is Customer Managed through the LCS API.", "Tags": [ "Environment", "Stop", "StartStop", "Start", "LCS", "Api" ], "Params": [ [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS\nDefault value can be configured using Set-D365LcsApiConfig", "", false, "false", "$Script:LcsApiProjectId" ], [ "BearerToken", "The token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "EnvironmentId", "The unique id of the environment that you want to take action upon\nThe Id can be located inside the LCS portal", "", true, "false", "" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "FailOnErrorMessage", "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", "", false, "false", "False" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi), Billy Richardson (@richardsondev)", "Synopsis": "Stop a specified environment through LCS.", "Name": "Invoke-D365LcsEnvironmentStop", "Links": [ null, null, null, null, null ], "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.", "Syntax": "Invoke-D365LcsEnvironmentStop [[-ProjectId] \u003cInt32\u003e] [[-BearerToken] \u003cString\u003e] [-EnvironmentId] \u003cString\u003e [[-LcsApiUri] \u003cString\u003e] [-FailOnErrorMessage] [[-RetryTimeout] \u003cTimeSpan\u003e] [-EnableException] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365LcsUpload", "Description": "Upload a file to a LCS project using the API provided by Microsoft", "Tags": [ "Environment", "Url", "Config", "Configuration", "LCS", "Upload", "Api", "AAD", "Token" ], "Params": [ [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS\nDefault value can be configured using Set-D365LcsApiConfig", "", false, "false", "$Script:LcsApiProjectId" ], [ "BearerToken", "The token you want to use when working against the LCS api\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "FilePath", "Path to the file that you want to upload to the Asset Library on LCS", "", true, "false", "" ], [ "FileType", "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\"", "", false, "false", "SoftwareDeployablePackage" ], [ "Name", "Name to be assigned / shown on LCS", "", false, "false", "" ], [ "Filename", "Filename to be assigned / shown on LCS\nOften will it require an extension for it to be accepted", "", false, "false", "" ], [ "FileDescription", "Description to be assigned / shown on LCS", "", false, "false", "" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "FailOnErrorMessage", "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", "", false, "false", "False" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Upload a file to a LCS project", "Name": "Invoke-D365LcsUpload", "Links": [ null, null, null, null, null, null, null ], "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.", "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]" }, { "CommandName": "Invoke-D365ModuleCompile", "Description": "Compile a package / module / model using the builtin \"xppc.exe\" executable to compile source code", "Tags": [ "Compile", "Model", "Servicing", "X++" ], "Params": [ [ "Module", "The package to compile", "ModuleName", true, "true (ByPropertyName)", "" ], [ "OutputDir", "The path to the folder to save generated artifacts", "Output", false, "false", "$Script:MetaDataDir" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModuleCompile\")" ], [ "MetaDataDir", "The path to the meta data directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "$Script:MetaDataDir" ], [ "ReferenceDir", "The full path of a folder containing all assemblies referenced from X++ code\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "$Script:MetaDataDir" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "$Script:BinDirTools" ], [ "XRefSqlServer", "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", "", false, "false", "$env:COMPUTERNAME" ], [ "XRefDbName", "The name of the cross references database; the default is \"DYNAMICSXREFDB\"\r\nThis parameter is only used for XRefGenerationOnly", "", false, "false", "DYNAMICSXREFDB" ], [ "XRefGeneration", "Instruct the cmdlet to enable the generation of XRef metadata while running the compile", "", false, "false", "False" ], [ "XRefGenerationOnly", "Instruct the cmdlet to only generate XRef metadata while running the compile and not update the assemblies and PDB files", "", false, "false", "False" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Ievgen Miroshnikov (@IevgenMir)", "Synopsis": "Compile a package / module / model", "Name": "Invoke-D365ModuleCompile", "Links": null, "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.", "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]" }, { "CommandName": "Invoke-D365ModuleFullCompile", "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", "Tags": [ "Compile", "Model", "Servicing" ], "Params": [ [ "Module", "The package to compile", "ModuleName", true, "true (ByPropertyName)", "" ], [ "OutputDir", "The path to the folder to save assemblies", "Output", false, "false", "$Script:MetaDataDir" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModuleCompile\")" ], [ "MetaDataDir", "The path to the meta data directory for the environment", "", false, "false", "$Script:MetaDataDir" ], [ "ReferenceDir", "The full path of a folder containing all assemblies referenced from X++ code", "", false, "false", "$Script:MetaDataDir" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "$Script:BinDirTools" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Ievgen Miroshnikov (@IevgenMir)", "Synopsis": "Compile a package", "Name": "Invoke-D365ModuleFullCompile", "Links": null, "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.", "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]" }, { "CommandName": "Invoke-D365ModuleLabelGeneration", "Description": "Generate labels for a package / module / model using the builtin \"labelc.exe\"", "Tags": [ "Compile", "Model", "Servicing", "Label", "Labels" ], "Params": [ [ "Module", "Name of the package that you want to work against", "ModuleName", true, "true (ByPropertyName)", "" ], [ "OutputDir", "The path to the folder to save generated artifacts", "Output", false, "false", "$Script:MetaDataDir" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModuleCompile\")" ], [ "MetaDataDir", "The path to the meta data directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "$Script:MetaDataDir" ], [ "ReferenceDir", "The full path of a folder containing all assemblies referenced from X++ code\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "$Script:MetaDataDir" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "$Script:BinDirTools" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Ievgen Miroshnikov (@IevgenMir)", "Synopsis": "Generate labels for a package / module / model", "Name": "Invoke-D365ModuleLabelGeneration", "Links": null, "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.", "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]" }, { "CommandName": "Invoke-D365ModuleReportsCompile", "Description": "Generate reports for a package / module / model using the builtin \"ReportsC.exe\"", "Tags": [ "Compile", "Model", "Servicing", "Report", "Reports" ], "Params": [ [ "Module", "Name of the package that you want to work against", "ModuleName", true, "true (ByPropertyName)", "" ], [ "OutputDir", "The path to the folder to save generated artifacts", "Output", false, "false", "$Script:MetaDataDir" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModuleCompile\")" ], [ "MetaDataDir", "The path to the meta data directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "$Script:MetaDataDir" ], [ "ReferenceDir", "The full path of a folder containing all assemblies referenced from X++ code\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "$Script:MetaDataDir" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "$Script:BinDirTools" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Ievgen Miroshnikov (@IevgenMir)", "Synopsis": "Generate reports for a package / module / model", "Name": "Invoke-D365ModuleReportsCompile", "Links": null, "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.", "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]" }, { "CommandName": "Invoke-D365ProcessModule", "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", "Tags": [ "Compile", "Model", "Servicing", "Database", "Synchronization" ], "Params": [ [ "Module", "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", "ModuleName", true, "false", "" ], [ "ExecuteCompile", "Switch/flag to determine if the compile function should be executed for requested modules", "", false, "false", "False" ], [ "ExecuteSync", "Switch/flag to determine if the databasesync function should be executed for requested modules", "", false, "false", "False" ], [ "ExecuteDeployReports", "Switch/flag to determine if the deploy reports function should be executed for requested modules", "", false, "false", "False" ], [ "OutputDir", "The path to the folder to save assemblies", "Output", false, "false", "$Script:MetaDataDir" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\ModuleCompile\")" ], [ "MetaDataDir", "The path to the meta data directory for the environment", "", false, "false", "$Script:MetaDataDir" ], [ "ReferenceDir", "The full path of a folder containing all assemblies referenced from X++ code", "", false, "false", "$Script:MetaDataDir" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "$Script:BinDirTools" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Jasper Callens - Cegeka", "Synopsis": "Process a specific or multiple modules (compile, deploy reports and sync)", "Name": "Invoke-D365ProcessModule", "Links": null, "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.", "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]" }, { "CommandName": "Invoke-D365ReArmWindows", "Description": "Function used for invoking the rearm functionality inside Windows", "Params": [ [ "Restart", "Instruct the cmdlet to restart the machine", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Invokes the Rearm of Windows license", "Name": "Invoke-D365ReArmWindows", "Links": null, "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.", "Syntax": "Invoke-D365ReArmWindows [[-Restart]] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365RunbookAnalyzer", "Description": "Get all the important details from a failed runbook", "Tags": [ "Runbook", "Servicing", "Hotfix", "DeployablePackage", "Deployable Package", "InstallationRecordsDirectory", "Installation Records Directory" ], "Params": [ [ "Path", "Path to the runbook file that you work against", "File", true, "true (ByValue, ByPropertyName)", "" ], [ "FailedOnly", "Instruct the cmdlet to only output failed steps", "", false, "false", "False" ], [ "FailedOnlyAsObjects", "Instruct the cmdlet to only output failed steps as objects", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Analyze the runbook", "Name": "Invoke-D365RunbookAnalyzer", "Links": null, "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.", "Syntax": "Invoke-D365RunbookAnalyzer -Path \u003cString\u003e [\u003cCommonParameters\u003e]\nInvoke-D365RunbookAnalyzer -Path \u003cString\u003e [-FailedOnlyAsObjects] [\u003cCommonParameters\u003e]\nInvoke-D365RunbookAnalyzer -Path \u003cString\u003e [-FailedOnly] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365SCDPBundleInstall", "Description": "A cmdlet that wraps some of the cumbersome work of installing updates / hotfixes into a streamlined process", "Tags": [ "Hotfix", "Hotfixes", "Updates", "Prepare", "VSTS", "axscdppkg" ], "Params": [ [ "InstallOnly", "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", "", true, "false", "False" ], [ "Command", "The command / job you want the cmdlet to execute\nValid options are:\r\nPrepare\r\nInstall\nDefault value is \"Prepare\"", "", false, "false", "Prepare" ], [ "Path", "Path to the update package that you want to install into the environment\nThe cmdlet only supports an already extracted \".axscdppkg\" file", "File,Hotfix", true, "false", "" ], [ "MetaDataDir", "The path to the meta data directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "\"$Script:MetaDataDir\"" ], [ "TfsWorkspaceDir", "The path to the TFS Workspace directory that you want to work against\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "\"$Script:MetaDataDir\"" ], [ "TfsUri", "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", "", false, "false", "\"$Script:TfsUri\"" ], [ "ShowModifiedFiles", "Switch to instruct the cmdlet to show all the modified files afterwards", "", false, "false", "False" ], [ "ShowProgress", "Switch to instruct the cmdlet to output progress details while servicing the installation", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@splaxi)", "Synopsis": "Invoke the SCDPBundleInstall.exe file", "Name": "Invoke-D365SCDPBundleInstall", "Links": null, "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.", "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]" }, { "CommandName": "Invoke-D365SDPInstall", "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", "Params": [ [ "Path", "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.", "File,Hotfix", true, "false", "" ], [ "MetaDataDir", "The path to the meta data directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "\"$Script:MetaDataDir\"" ], [ "QuickInstallAll", "Use this switch to let the runbook reside in memory. You will not get a runbook on disc which you can examine for steps", "", false, "false", "False" ], [ "DevInstall", "Use this when running on developer box without administrator privileges (Run As Administrator)", "", false, "false", "False" ], [ "Command", "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\"", "", true, "false", "SetTopology" ], [ "Step", "The step number that you want to work against", "", false, "false", "0" ], [ "RunbookId", "The runbook id of the runbook that you want to work against\nDefault value is \"Runbook\"", "", false, "false", "Runbook" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\SdpInstall\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ], [ "TopologyFile", "Provide a custom topology file to use. By default, the cmdlet will use the DefaultTopologyData.xml file in the package directory.", "", false, "false", "DefaultTopologyData.xml" ], [ "UseExistingTopologyFile", "Use this switch to indicate that the topology file is already updated and should not be updated again.", "", false, "false", "False" ], [ "UnifiedDevelopmentEnvironment", "Use this switch to install the package in a Unified Development Environment (UDE).", "", false, "false", "False" ], [ "IncludeFallbackRetailServiceModels", "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", "", false, "false", "False" ], [ "Force", "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.", "", false, "false", "False" ], [ "ForceFallbackServiceModels", "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.", "", false, "false", "False" ] ], "Alias": "", "Author": "Tommy Skaue (@skaue)", "Synopsis": "Install a Software Deployable Package (SDP)", "Name": "Invoke-D365SDPInstall", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\package.zip\" -QuickInstallAll\nThis will install the package contained in the c:\\temp\\package.zip file using a runbook in memory while executing.\n-------------------------- EXAMPLE 2 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -DevInstall\nThis will install the extracted package in c:\\temp\\ using a runbook in memory while executing.\nThis command is to be used on Microsoft Hosted Tier1 development environment, where you don\u0027t have access to the administrator user account on the vm.\n-------------------------- EXAMPLE 3 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command SetTopology\nPS C:\\\u003e Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command Generate -RunbookId \u0027MyRunbook\u0027\r\nPS C:\\\u003e Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command Import -RunbookId \u0027MyRunbook\u0027\r\nPS C:\\\u003e Invoke-D365SDPInstall -Path \"c:\\temp\\\" -Command Execute -RunbookId \u0027MyRunbook\u0027\nManual operations that first create Topology XML from current environment, then generate runbook with id \u0027MyRunbook\u0027, then import it and finally execute it.\n-------------------------- EXAMPLE 4 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RunAll\nCreate Topology XML from current environment. Using default runbook id \u0027Runbook\u0027 and run all the operations from generate, to import to execute.\n-------------------------- EXAMPLE 5 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command RerunStep -Step 18 -RunbookId \u0027MyRunbook\u0027\nRerun runbook with id \u0027MyRunbook\u0027 from step 18.\n-------------------------- EXAMPLE 6 --------------------------\nPS C:\\\u003eInvoke-D365SDPInstall -Path \"c:\\temp\\\" -Command SetStepComplete -Step 24 -RunbookId \u0027MyRunbook\u0027\nMark step 24 complete in runbook with id \u0027MyRunbook\u0027 and continue the runbook from the next step.\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.", "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]" }, { "CommandName": "Invoke-D365SDPInstallUDE", "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.", "Params": [ [ "Path", "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.", "File,Hotfix", true, "false", "" ], [ "MetaDataDir", "The path to the meta data directory for the environment", "", true, "false", "" ], [ "LogPath", "The path where the log file(s) will be saved", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\SdpInstall\")" ], [ "Force", "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.", "", false, "false", "False" ] ], "Alias": "", "Author": "Florian Hopfner (@FH-Inway)", "Synopsis": "Install a Software Deployable Package (SDP) in a unified development environment", "Name": "Invoke-D365SDPInstallUDE", "Links": null, "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.", "Syntax": "Invoke-D365SDPInstallUDE [-Path] \u003cString\u003e [-MetaDataDir] \u003cString\u003e [-LogPath \u003cString\u003e] [-Force] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365SeleniumDownload", "Description": "Downloads the Selenium web driver files and deploys them to the specified destinations.", "Params": [ [ "RegressionSuiteAutomationTool", "Switch to specify if the Selenium files need to be installed in the Regression Suite Automation Tool folder.", "", false, "false", "False" ], [ "PerfSDK", "Switch to specify if the Selenium files need to be installed in the PerfSDK folder.", "", false, "false", "False" ] ], "Alias": "", "Author": "Kenny Saelen (@kennysaelen)", "Synopsis": "Downloads the Selenium web driver files and deploys them to the specified destinations.", "Name": "Invoke-D365SeleniumDownload", "Links": null, "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.", "Syntax": "Invoke-D365SeleniumDownload [[-RegressionSuiteAutomationTool]] [[-PerfSDK]] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365SqlScript", "Description": "Execute a SQL Script or a SQL Command against the D365FO SQL Server database", "Params": [ [ "FilePath", "Path to the file containing the SQL Script that you want executed", "", true, "false", "" ], [ "Command", "SQL command that you want executed", "", true, "false", "" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "TrustedConnection", "Switch to instruct the cmdlet whether the connection should be using Windows Authentication or not", "", false, "false", "False" ], [ "EnableException", "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", "", false, "false", "False" ], [ "NoPooling", "Should the connection use connection pooling or not", "", false, "false", "False" ] ], "Alias": "Invoke-D365SqlCmd", "Author": "Mötz Jensen (@splaxi)", "Synopsis": "Execute a SQL Script or a SQL Command", "Name": "Invoke-D365SqlScript", "Links": null, "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.", "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]" }, { "CommandName": "Invoke-D365SysFlushAodCache", "Description": "Invoke the runnable class SysFlushAos to clear the AOD cache", "Params": [ [ "Url", "URL to the Dynamics 365 instance you want to clear the AOD cache on", "", false, "false", "" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Invoke the SysFlushAos class", "Name": "Invoke-D365SysFlushAodCache", "Links": null, "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", "Syntax": "Invoke-D365SysFlushAodCache [[-Url] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365SysRunnerClass", "Description": "Makes it possible to call any runnable class directly from the browser, without worrying about the details", "Params": [ [ "ClassName", "The name of the class you want to execute", "", true, "false", "" ], [ "Company", "The company for which you want to execute the class against\nDefault value is: \"DAT\"", "", false, "false", "$Script:Company" ], [ "Url", "The URL you want to execute against\nDefault value is the Fully Qualified Domain Name registered on the machine", "", false, "false", "$Script:Url" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Start a browser session that executes SysRunnerClass", "Name": "Invoke-D365SysRunnerClass", "Links": null, "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", "Syntax": "Invoke-D365SysRunnerClass [-ClassName] \u003cString\u003e [[-Company] \u003cString\u003e] [[-Url] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365TableBrowser", "Description": "Makes it possible to call the table browser for a given table directly from the web browser, without worrying about the details", "Params": [ [ "TableName", "The name of the table you want to see the rows for", "", true, "true (ByPropertyName)", "" ], [ "Company", "The company for which you want to see the data from in the given table\nDefault value is: \"DAT\"", "", false, "true (ByPropertyName)", "$Script:Company" ], [ "Url", "The URL you want to execute against\nDefault value is the Fully Qualified Domain Name registered on the machine", "", false, "true (ByPropertyName)", "$Script:Url" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Start a browser session that will show the table browser", "Name": "Invoke-D365TableBrowser", "Links": null, "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.", "Syntax": "Invoke-D365TableBrowser [-TableName] \u003cString\u003e [[-Company] \u003cString\u003e] [[-Url] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365VisualStudioCompilerResultAnalyzer", "Description": "Analyze the Visual Studio compiler output log and generate an excel file contain worksheets per type: Errors, Warnings, Tasks", "Tags": [ "Compiler", "Build", "Errors", "Warnings", "Tasks" ], "Params": [ [ "Module", "Name of the module that you want to work against\nDefault value is \"*\" which will search for all modules", "ModuleName", false, "false", "*" ], [ "OutputPath", "Path where you want the excel file (xlsx-file) saved to\nDefault value is: \"c:\\temp\\d365fo.tools\\\"", "", false, "false", "$Script:DefaultTempPath" ], [ "SkipWarnings", "Instructs the cmdlet to skip warnings while analyzing the compiler output log file", "", false, "false", "False" ], [ "SkipTasks", "Instructs the cmdlet to skip tasks while analyzing the compiler output log file", "", false, "false", "False" ], [ "PackageDirectory", "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", "", false, "false", "$Script:PackageDirectory" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Analyze the Visual Studio compiler output log", "Name": "Invoke-D365VisualStudioCompilerResultAnalyzer", "Links": null, "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", "Syntax": "Invoke-D365VisualStudioCompilerResultAnalyzer [[-Module] \u003cString\u003e] [[-OutputPath] \u003cString\u003e] [-SkipWarnings] [-SkipTasks] [[-PackageDirectory] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Invoke-D365WinRmCertificateRotation", "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", "Params": [ [ "MachineName", "The DNS / Netbios name of the machine\nThe default value is: \"$env:COMPUTERNAME\" which translates into the current name of the machine", "", false, "false", "$env:COMPUTERNAME" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Rotate the certificate used for WinRM", "Name": "Invoke-D365WinRmCertificateRotation", "Links": null, "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.", "Syntax": "Invoke-D365WinRmCertificateRotation [[-MachineName] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "New-D365Bacpac", "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", "Params": [ [ "ExportModeTier1", "Switch to instruct the cmdlet that the export will be done against a classic SQL Server installation", "", true, "false", "False" ], [ "ExportModeTier2", "Switch to instruct the cmdlet that the export will be done against an Azure SQL DB instance", "", true, "false", "False" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "BackupDirectory", "The path where to store the temporary backup file when the script needs to handle that", "", false, "false", "C:\\Temp\\d365fo.tools\\SqlBackups" ], [ "NewDatabaseName", "The name for the database the script is going to create when doing the restore process", "", false, "false", "\"$Script:DatabaseName`_export\"" ], [ "BacpacFile", "The path where you want the cmdlet to store the bacpac file that will be generated", "File", false, "false", "\"C:\\Temp\\d365fo.tools\\$DatabaseName.bacpac\"" ], [ "CustomSqlFile", "The path to a custom sql server script file that you want executed against the database before it is exported", "", false, "false", "" ], [ "DiagnosticFile", "Path to where you want the export to output a diagnostics file to assist you in troubleshooting the export", "", false, "false", "" ], [ "ExportOnly", "Switch to instruct the cmdlet to either just create a dump bacpac file or run the prepping process first", "", false, "false", "False" ], [ "MaxParallelism", "Sets SqlPackage.exe\u0027s degree of parallelism for concurrent operations running against a database. The default value is 8.", "", false, "false", "8" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Rasmus Andersen (@ITRasmus)", "Synopsis": "Generate a bacpac file from a database", "Name": "New-D365Bacpac", "Links": null, "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.", "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]" }, { "CommandName": "New-D365CAReport", "Description": "A cmdlet that wraps some of the cumbersome work into a streamlined process", "Params": [ [ "OutputPath", "Path where you want the CAR file (xlsx-file) saved to\nDefault value is: \"c:\\temp\\d365fo.tools\\CAReport.xlsx\"", "Path,File", false, "false", "(Join-Path $Script:DefaultTempPath \"CAReport.xlsx\")" ], [ "Module", "Name of the Module to analyse", "ModuleName,Package", true, "false", "" ], [ "Model", "Name of the Model to analyse", "", true, "false", "" ], [ "SuffixWithModule", "Instruct the cmdlet to append the module name as a suffix to the desired output file name", "", false, "false", "False" ], [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the AOS service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:PackageDirectory\\bin\"" ], [ "MetaDataDir", "The path to the meta data directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "\"$Script:MetaDataDir\"" ], [ "XmlLog", "Path where you want to store the Xml log output generated from the best practice analyser", "", false, "false", "(Join-Path $Script:DefaultTempPath \"BPCheckLogcd.xml\")" ], [ "PackagesRoot", "Instructs the cmdlet to use binary metadata", "", false, "false", "False" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\CAReport\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Tommy Skaue (@Skaue)", "Synopsis": "Generate the Customization\u0027s Analysis Report (CAR)", "Name": "New-D365CAReport", "Links": null, "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.", "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]" }, { "CommandName": "New-D365EntraIntegration", "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.", "Params": [ [ "ClientId", "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.", "AppId", true, "false", "" ], [ "ExistingCertificateFile", "The path to a certificate file. If this parameter is provided, the cmdlet will not create a new certificate.", "", true, "false", "" ], [ "ExistingCertificatePrivateKeyFile", "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.", "", false, "false", "" ], [ "CertificateName", "The name for the certificate. By default, it is named \"CHEAuth\".", "", false, "false", "CHEAuth" ], [ "CertificateExpirationYears", "The number of years the certificate is valid. By default, it is valid for 2 years.", "", false, "false", "2" ], [ "NewCertificateFile", "The path to the certificate file that will be created. By default, it is created on the Desktop of the current user.", "", false, "false", "\"$env:USERPROFILE\\Desktop\\$CertificateName.cer\"" ], [ "NewCertificatePrivateKeyFile", "The path to the certificate private key file that will be created. By default, it is created on the Desktop of the current user.", "", false, "false", "\"$env:USERPROFILE\\Desktop\\$CertificateName.pfx\"" ], [ "CertificatePassword", "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.", "", false, "false", "" ], [ "Force", "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.", "", false, "false", "False" ], [ "WhatIf", "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.", "wi", false, "false", "" ], [ "Confirm", "Prompts for confirmation before each operation of the cmdlet that changes the state of the system.", "cf", false, "false", "" ] ], "Alias": "", "Author": "Øystein Brenna (@oysbre)", "Synopsis": "Enable the Microsoft Entra ID integration on a cloud hosted environment (CHE).", "Name": "New-D365EntraIntegration", "Links": null, "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.", "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]" }, { "CommandName": "New-D365ISVLicense", "Description": "Create a deployable package with a license file inside", "Params": [ [ "LicenseFile", "Path to the license file that you want to have inside a deployable package", "", true, "false", "" ], [ "Path", "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\"", "Template", false, "false", "\"$Script:BinDirTools\\CustomDeployablePackage\\ImportISVLicense.zip\"" ], [ "OutputPath", "Path where you want the generated deployable package stored\nDefault value is: \"C:\\temp\\d365fo.tools\\ISVLicense.zip\"", "", false, "false", "C:\\temp\\d365fo.tools\\ISVLicense.zip" ] ], "Alias": "", "Author": "Mötz Jensen (@splaxi)", "Synopsis": "Create a license deployable package", "Name": "New-D365ISVLicense", "Links": null, "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\"", "Syntax": "New-D365ISVLicense [-LicenseFile] \u003cString\u003e [-Path \u003cString\u003e] [-OutputPath \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "New-D365ModuleToRemove", "Description": "Create a new ModuleToRemove.txt file based on a list of module names", "Params": [ [ "Path", "Path to the ModuleToRemove.txt file", "Folder", true, "false", "" ], [ "Modules", "The array with all the module names that you want to fill into the ModuleToRemove.txt file", "", true, "false", "" ] ], "Alias": "", "Author": "Florian Hopfner (@FH-Inway)", "Synopsis": "Create a new ModuleToRemove.txt file", "Name": "New-D365ModuleToRemove", "Links": null, "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.", "Syntax": "New-D365ModuleToRemove [-Path] \u003cString\u003e [-Modules] \u003cString[]\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "New-D365TopologyFile", "Description": "Build a new topology file based on a template and update the ServiceModelList", "Params": [ [ "Path", "Path to the template topology file", "File", true, "false", "" ], [ "Services", "The array with all the service names that you want to fill into the topology file", "", true, "false", "" ], [ "NewPath", "Path to where you want to save the new file after it has been created", "NewFile", true, "false", "" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Create a new topology file", "Name": "New-D365TopologyFile", "Links": null, "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\"", "Syntax": "New-D365TopologyFile [-Path] \u003cString\u003e [-Services] \u003cString[]\u003e [-NewPath] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Publish-D365SsrsReport", "Description": "Deploy SSRS Report to SQL Server Reporting Services", "Tags": [ "SSRS", "Report", "Reports", "Deploy", "Publish" ], "Params": [ [ "Module", "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", "", false, "false", "*" ], [ "ReportName", "Name of the report that you want to deploy\nDefault value is \"*\" and will deploy all reports from the module(s) that you speficied", "", false, "false", "*" ], [ "LogFile", "Path to the file that should contain the logging information\nDefault value is \"c:\\temp\\d365fo.tools\\AxReportDeployment.log\"", "", false, "false", "(Join-Path $Script:DefaultTempPath \"AxReportDeployment.log\")" ], [ "PackageDirectory", "Path to the PackagesLocalDirectory\nDefault path is the same as the AOS Service PackagesLocalDirectory", "", false, "false", "$Script:PackageDirectory" ], [ "ToolsBasePath", "Base path to the folder containing the needed PowerShell manifests that the cmdlet utilizes\nDefault path is the same as the AOS Service PackagesLocalDirectory", "", false, "false", "$Script:PackageDirectory" ], [ "ReportServerIp", "IP Address of the server that has SQL Reporting Services installed\nDefault value is \"127.0.01\"", "", false, "false", "127.0.0.1" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Deploy Report", "Name": "Publish-D365SsrsReport", "Links": null, "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.", "Syntax": "Publish-D365SsrsReport [[-Module] \u003cString[]\u003e] [[-ReportName] \u003cString[]\u003e] [[-LogFile] \u003cString\u003e] [[-PackageDirectory] \u003cString\u003e] [[-ToolsBasePath] \u003cString\u003e] [[-ReportServerIp] \u003cString[]\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Publish-D365WebResources", "Description": "Deploys the Dynamics 365 for Finance and Operations web resources to the AOS service web root path.", "Params": [ [ "PackageDirectory", "Path to the package directory containing the web resources.", "", false, "false", "$Script:PackageDirectory" ], [ "AosServiceWebRootPath", "Path to the AOS service web root path.", "", false, "false", "$Script:AOSPath" ] ], "Alias": "", "Author": "Florian Hopfner (@FH-Inway)", "Synopsis": "Deploy web resources", "Name": "Publish-D365WebResources", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003ePublish-D365WebResources\nThis will deploy the web resources to the AOS service web root path.", "Syntax": "Publish-D365WebResources [[-PackageDirectory] \u003cPathDirectoryParameter\u003e] [[-AosServiceWebRootPath] \u003cPathDirectoryParameter\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Register-D365AzureStorageConfig", "Description": "Register all Azure Storage Configurations", "Tags": [ "Configuration", "Azure", "Storage" ], "Params": [ [ "ConfigStorageLocation", "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", "", false, "false", "User" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Register Azure Storage Configurations", "Name": "Register-D365AzureStorageConfig", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eRegister-D365AzureStorageConfig -ConfigStorageLocation \"System\"\nThis will store all Azure Storage Configurations as defaults for all users on the machine.", "Syntax": "Register-D365AzureStorageConfig [[-ConfigStorageLocation] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Remove-D365BroadcastMessageConfig", "Description": "Remove a broadcast message configuration from the configuration store", "Tags": [ "Servicing", "Broadcast", "Message", "Users", "Environment", "Config", "Configuration", "ClientId", "ClientSecret" ], "Params": [ [ "Name", "Name of the broadcast message configuration you want to remove from the configuration store", "", true, "false", "" ], [ "Temporary", "Instruct the cmdlet to only temporarily remove the broadcast message configuration from the configuration store", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Remove broadcast message configuration", "Name": "Remove-D365BroadcastMessageConfig", "Links": [ null, null, null, null, null, null ], "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eRemove-D365BroadcastMessageConfig -Name \"UAT\"\nThis will remove the broadcast message configuration name \"UAT\" from the machine.", "Syntax": "Remove-D365BroadcastMessageConfig [-Name] \u003cString\u003e [-Temporary] [\u003cCommonParameters\u003e]" }, { "CommandName": "Remove-D365Database", "Description": "Removes a database. By default, if no other database is specified, the AxDB database will be removed.", "Params": [ [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "EnableException", "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", "", false, "false", "False" ], [ "Force", "This parameter will suppress the confirmation prompt. It can be used as an alternative to -Confirm:$false", "", false, "false", "False" ], [ "WhatIf", "This parameter will simulate the actions of the command. No changes will be made.", "wi", false, "false", "" ], [ "Confirm", "This parameter will prompt you for confirmation before executing steps of the command that have a medium impact.", "cf", false, "false", "" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Removes a database", "Name": "Remove-D365Database", "Links": null, "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.", "Syntax": "Remove-D365Database [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [-EnableException] [-Force] [-WhatIf] [-Confirm] [\u003cCommonParameters\u003e]" }, { "CommandName": "Remove-D365LcsAssetFile", "Description": "Delete asset from the LCS project Asset Library", "Params": [ [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS\r\nDefault value can be configured using Set-D365LcsApiConfig", "", false, "false", "$Script:LcsApiProjectId" ], [ "AssetId", "LCS Id of the file that you are looking for", "", true, "false", "" ], [ "BearerToken", "The token you want to use when working against the LCS api\r\nDefault value can be configured using Set-D365LcsApiConfig", "Token", false, "false", "$Script:LcsApiBearerToken" ], [ "LcsApiUri", "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", "", false, "false", "$Script:LcsApiLcsApiUri" ], [ "RetryTimeout", "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", "", false, "false", "00:00:00" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Oleksandr Nikolaiev (@onikolaiev)", "Synopsis": "Delete asset from the LCS project Asset Library", "Name": "Remove-D365LcsAssetFile", "Links": [ null, null, null, null, null ], "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).", "Syntax": "Remove-D365LcsAssetFile [[-ProjectId] \u003cInt32\u003e] [-AssetId] \u003cString\u003e [[-BearerToken] \u003cString\u003e] [[-LcsApiUri] \u003cString\u003e] [[-RetryTimeout] \u003cTimeSpan\u003e] [-EnableException] [\u003cCommonParameters\u003e]" }, { "CommandName": "Remove-D365Model", "Description": "Remove a model from a Dynamics 365 for Finance \u0026 Operations environment", "Tags": [ "ModelUtil", "Axmodel", "Model", "Remove", "Delete", "Source Control", "Vsts", "Azure DevOps" ], "Params": [ [ "Model", "Name of the model that you want to work against", "", true, "false", "" ], [ "BinDir", "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", "", false, "false", "\"$Script:PackageDirectory\\bin\"" ], [ "MetaDataDir", "The path to the meta data directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory", "", false, "false", "\"$Script:MetaDataDir\"" ], [ "DeleteFolders", "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", "", false, "false", "False" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Remove a model from Dynamics 365 for Finance \u0026 Operations", "Name": "Remove-D365Model", "Links": null, "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.", "Syntax": "Remove-D365Model [-Model] \u003cString\u003e [[-BinDir] \u003cString\u003e] [[-MetaDataDir] \u003cString\u003e] [-DeleteFolders] [-ShowOriginalProgress] [-OutputCommandOnly] [\u003cCommonParameters\u003e]" }, { "CommandName": "Remove-D365User", "Description": "Deletes the user from the database, including security configuration", "Params": [ [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "Email", "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.", "", true, "true (ByPropertyName)", "" ] ], "Alias": "", "Author": "Rasmus Andersen (@ITRasmus)", "Synopsis": "Delete an user from the environment", "Name": "Remove-D365User", "Links": null, "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.", "Syntax": "Remove-D365User [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [-Email] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Rename-D365ComputerName", "Description": "When doing development on-prem, there is as need for changing the Computername.\nFunction both changes Computername and SSRS Configuration", "Params": [ [ "NewName", "The new name for the computer", "", true, "false", "" ], [ "SSRSReportDatabase", "Name of the SSRS reporting database", "", false, "false", "DynamicsAxReportServer" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "LogPath", "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", "LogDir", false, "false", "$(Join-Path -Path $Script:DefaultTempPath -ChildPath \"Logs\\RsConfig\")" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ], [ "OutputCommandOnly", "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", "", false, "false", "False" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Rasmus Andersen (@ITRasmus)", "Synopsis": "Function for renaming computer.\nRenames Computer and changes the SSRS Configration", "Name": "Rename-D365ComputerName", "Links": null, "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.", "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]" }, { "CommandName": "Rename-D365Instance", "Description": "The Rename function, changes the config values used by a D365FO dev box for identifying its name. Standard it is called \u0027usnconeboxax1aos\u0027", "Params": [ [ "NewName", "The new name wanted for the D365FO instance", "", true, "false", "" ], [ "AosServiceWebRootPath", "Path to the webroot folder for the AOS service \u0027Default value : C:\\AOSService\\Webroot", "", false, "false", "$Script:AOSPath" ], [ "IISServerApplicationHostConfigFile", "Path to the IISService Application host file, [Where the binding configurations is stored] \u0027Default value : C:\\Windows\\System32\\inetsrv\\Config\\applicationHost.config\u0027", "", false, "false", "$Script:IISHostFile" ], [ "HostsFile", "Place of the host file on the current system [Local DNS record] \u0027 Default value C:\\Windows\\System32\\drivers\\etc\\hosts\u0027", "", false, "false", "$Script:Hosts" ], [ "BackupExtension", "Backup name for all the files that are changed", "", false, "false", "bak" ], [ "MRConfigFile", "Path to the Financial Reporter (Management Reporter) configuration file", "", false, "false", "$Script:MRConfigFile" ] ], "Alias": "", "Author": "Rasmus Andersen (@ITRasmus)", "Synopsis": "Rename as D365FO Demo/Dev box", "Name": "Rename-D365Instance", "Links": null, "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.", "Syntax": "Rename-D365Instance [-NewName] \u003cString\u003e [[-AosServiceWebRootPath] \u003cString\u003e] [[-IISServerApplicationHostConfigFile] \u003cString\u003e] [[-HostsFile] \u003cString\u003e] [[-BackupExtension] \u003cString\u003e] [[-MRConfigFile] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Repair-D365BacpacModelFile", "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", "Params": [ [ "Path", "Path to the bacpac model file that you want to work against", "", true, "false", "" ], [ "OutputPath", "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", "", false, "false", "" ], [ "PathRepairSimple", "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", "", false, "false", "\"$script:ModuleRoot\\internal\\misc\\RepairBacpac.Simple.json\"" ], [ "PathRepairQualifier", "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", "", false, "false", "\"$script:ModuleRoot\\internal\\misc\\RepairBacpac.Qualifier.json\"" ], [ "PathRepairReplace", "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", "", false, "false", "\"$script:ModuleRoot\\internal\\misc\\RepairBacpac.Replace.json\"" ], [ "KeepFiles", "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", "", false, "false", "False" ], [ "Force", "Instruct the cmdlet to overwrite the file specified in the OutputPath if it already exists", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Repair a bacpac model file", "Name": "Repair-D365BacpacModelFile", "Links": null, "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.", "Syntax": "Repair-D365BacpacModelFile [-Path] \u003cString\u003e [[-OutputPath] \u003cString\u003e] [[-PathRepairSimple] \u003cString\u003e] [[-PathRepairQualifier] \u003cString\u003e] [[-PathRepairReplace] \u003cString\u003e] [-KeepFiles] [-Force] [\u003cCommonParameters\u003e]" }, { "CommandName": "Restart-D365Environment", "Description": "Restart the different services in a Dynamics 365 Finance \u0026 Operations environment", "Tags": [ "Environment", "Service", "Services", "Aos", "Batch", "Servicing" ], "Params": [ [ "ComputerName", "An array of computers that you want to work against", "", false, "false", "@($env:computername)" ], [ "All", "Instructs the cmdlet work against all relevant services\nIncludes:\r\nAos\r\nBatch\r\nFinancial Reporter\r\nDMF", "", false, "false", "True" ], [ "Aos", "Instructs the cmdlet to work against the AOS (IIS) service", "", false, "false", "False" ], [ "Batch", "Instructs the cmdlet to work against the Batch service", "", false, "false", "False" ], [ "FinancialReporter", "Instructs the cmdlet to work against the Financial Reporter (Management Reporter 2012)", "", false, "false", "False" ], [ "DMF", "Instructs the cmdlet to work against the DMF service", "", false, "false", "False" ], [ "Kill", "Instructs the cmdlet to kill the service(s) that you want to restart", "", false, "false", "False" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Restart the different services", "Name": "Restart-D365Environment", "Links": null, "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.", "Syntax": "Restart-D365Environment [[-ComputerName] \u003cString[]\u003e] [[-All]] [-Kill] [-ShowOriginalProgress] [\u003cCommonParameters\u003e]\nRestart-D365Environment [[-ComputerName] \u003cString[]\u003e] [[-Aos]] [[-Batch]] [[-FinancialReporter]] [[-DMF]] [-Kill] [-ShowOriginalProgress] [\u003cCommonParameters\u003e]" }, { "CommandName": "Restore-D365DevConfig", "Description": "Will restore the DynamicsDevConfig.xml file located in the PackagesLocalDirectory\\Bin folder", "Tags": [ "Web Server", "IIS", "IIS Express", "Development" ], "Params": [ [ "Path", "Path to the folder where you the desired DynamicsDevConfig.xml file that you want restored is located\nDefault is: \"C:\\Temp\\d365fo.tools\\DevConfigBackup\"", "", false, "false", "$(Join-Path $Script:DefaultTempPath \"DevConfigBackup\")" ], [ "Force", "Instructs the cmdlet to overwrite the destination file if it already exists", "", false, "false", "False" ] ], "Alias": "", "Author": "Sander Holvoet (@smholvoet)", "Synopsis": "Restore the DynamicsDevConfig.xml file", "Name": "Restore-D365DevConfig", "Links": null, "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", "Syntax": "Restore-D365DevConfig [[-Path] \u003cString\u003e] [-Force] [\u003cCommonParameters\u003e]" }, { "CommandName": "Restore-D365WebConfig", "Description": "Will restore the web.config file located back into the AOS / IIS folder", "Tags": [ "DEV", "Tier2", "DB", "Database", "Debug", "JIT", "LCS", "Azure DB" ], "Params": [ [ "Path", "Path to the folder where you the desired web.config file that you want restored is located\nDefault is: \"C:\\Temp\\d365fo.tools\\WebConfigBackup\"", "", false, "false", "$(Join-Path $Script:DefaultTempPath \"WebConfigBackup\")" ], [ "Force", "Instructs the cmdlet to overwrite the destination file if it already exists", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Restore the web.config file", "Name": "Restore-D365WebConfig", "Links": null, "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", "Syntax": "Restore-D365WebConfig [[-Path] \u003cString\u003e] [-Force] [\u003cCommonParameters\u003e]" }, { "CommandName": "Send-D365BroadcastMessage", "Description": "Utilize the same messaging framework available from LCS and send a broadcast message to all online users in the environment", "Tags": [ "Servicing", "Message", "Users", "Environment" ], "Params": [ [ "Tenant", "Azure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to send a message to", "$AADGuid", false, "false", "$Script:BroadcastTenant" ], [ "URL", "URL / URI for the D365FO environment you want to send a message to", "URI", false, "false", "$Script:BroadcastUrl" ], [ "ClientId", "The ClientId obtained from the Azure Portal when you created a Registered Application", "", false, "false", "$Script:BroadcastClientId" ], [ "ClientSecret", "The ClientSecret obtained from the Azure Portal when you created a Registered Application", "", false, "false", "$Script:BroadcastClientSecret" ], [ "TimeZone", "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\"", "", false, "false", "$Script:BroadcastTimeZone" ], [ "StartTime", "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.", "", false, "false", "(Get-Date)" ], [ "EndingInMinutes", "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.", "", false, "false", "$Script:BroadcastEndingInMinutes" ], [ "OnPremise", "Specify if environnement is an D365 OnPremise\nDefault value is \"Not set\" (= Cloud Environnement)", "", false, "false", "$Script:BroadcastOnPremise" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Send broadcast message to online users in D365FO", "Name": "Send-D365BroadcastMessage", "Links": [ null, null, null, null, null, null ], "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.", "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]" }, { "CommandName": "Set-D365ActiveAzureStorageConfig", "Description": "Updates the current active Azure Storage Account configuration with a new one", "Params": [ [ "Name", "The name the Azure Storage Account configuration you want to load into the active Azure Storage Account configuration", "", false, "false", "" ], [ "ConfigStorageLocation", "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", "", false, "false", "User" ], [ "Temporary", "Instruct the cmdlet to only temporarily override the persisted settings in the configuration storage", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Set the active Azure Storage Account configuration", "Name": "Set-D365ActiveAzureStorageConfig", "Links": null, "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.", "Syntax": "Set-D365ActiveAzureStorageConfig [[-Name] \u003cString\u003e] [[-ConfigStorageLocation] \u003cString\u003e] [-Temporary] [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365ActiveBroadcastMessageConfig", "Description": "Updates the current active broadcast message configuration with a new one", "Tags": [ "Servicing", "Message", "Users", "Environment", "Config", "Configuration", "ClientId", "ClientSecret", "OnPremise" ], "Params": [ [ "Name", "Name of the broadcast message configuration you want to load into the active broadcast message configuration", "", true, "false", "" ], [ "Temporary", "Instruct the cmdlet to only temporarily override the persisted settings in the configuration store", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Set the active broadcast message configuration", "Name": "Set-D365ActiveBroadcastMessageConfig", "Links": [ null, null, null, null, null, null ], "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eSet-D365ActiveBroadcastMessageConfig -Name \"UAT\"\nThis will set the broadcast message configuration named \"UAT\" as the active configuration.", "Syntax": "Set-D365ActiveBroadcastMessageConfig [-Name] \u003cString\u003e [-Temporary] [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365Admin", "Description": "Cmdlet using the AdminProvisioning tool from D365FO", "Params": [ [ "AdminSignInName", "Email for the Admin", "Email", true, "false", "" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Rasmus Andersen (@ITRasmus)", "Synopsis": "Powershell implementation of the AdminProvisioning tool", "Name": "Set-D365Admin", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eSet-D365Admin \"claire@contoso.com\"\nThis will provision claire@contoso.com as administrator for the environment", "Syntax": "Set-D365Admin [-AdminSignInName] \u003cString\u003e [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [-EnableException] [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365AzCopyPath", "Description": "Update the path where the module will be looking for the AzCopy.exe executable", "Params": [ [ "Path", "Path to the AzCopy.exe", "", true, "false", "" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Set the path for AzCopy.exe", "Name": "Set-D365AzCopyPath", "Links": null, "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", "Syntax": "Set-D365AzCopyPath [-Path] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365ClickOnceTrustPrompt", "Description": "Creates the needed registry keys and values for ClickOnce to work on the machine", "Params": [ ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Set the ClickOnce needed configuration", "Name": "Set-D365ClickOnceTrustPrompt", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eSet-D365ClickOnceTrustPrompt\nThis will create / or update the current ClickOnce configuration.", "Syntax": "Set-D365ClickOnceTrustPrompt [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365DefaultModelForNewProjects", "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", "Params": [ [ "Module", "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", "Model", true, "true (ByValue, ByPropertyName)", "" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Set the default model used creating new projects in Visual Studio", "Name": "Set-D365DefaultModelForNewProjects", "Links": null, "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.", "Syntax": "Set-D365DefaultModelForNewProjects [-Module] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365FavoriteBookmark", "Description": "Enable the favorite bar in Edge \u0026 Chrome and put in the URL as a favorite/bookmark", "Params": [ [ "URL", "The URL of the shortcut you want to add to the favorite bar", "", false, "true (ByPropertyName)", "" ], [ "D365FO", "Instruct the cmdlet that you want the populate the D365FO favorite entry based on the URL provided", "", false, "false", "False" ], [ "AzureDevOps", "Instruct the cmdlet that you want the populate the AzureDevOps favorite entry based on the URL provided", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Enable the favorite bar and add an URL", "Name": "Set-D365FavoriteBookmark", "Links": null, "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.", "Syntax": "Set-D365FavoriteBookmark [-URL \u003cString\u003e] [-D365FO] [\u003cCommonParameters\u003e]\nSet-D365FavoriteBookmark [-URL \u003cString\u003e] [-AzureDevOps] [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365FlightServiceCatalogId", "Description": "Set the FlightingServiceCatalogID element in the web.config file used by D365FO", "Tags": [ "Flight", "Flighting" ], "Params": [ [ "FlightServiceCatalogId", "Flighting catalog ID to be set", "", false, "false", "12719367" ], [ "AosServiceWebRootPath", "Path to the root folder where to locate the web.config file", "", false, "false", "$Script:AOSPath" ] ], "Alias": "", "Author": "Frank Hüther(@FrankHuether))", "Synopsis": "Set the FlightingServiceCatalogID", "Name": "Set-D365FlightServiceCatalogId", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eSet-D365FlightServiceCatalogId\nThis will set the FlightingServiceCatalogID element the web.config to the default value \"12719367\".", "Syntax": "Set-D365FlightServiceCatalogId [[-FlightServiceCatalogId] \u003cString\u003e] [[-AosServiceWebRootPath] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365LcsApiConfig", "Description": "Set the LCS configuration details and save them into the configuration store", "Tags": [ "Environment", "Url", "Config", "Configuration", "LCS", "Upload", "ClientId" ], "Params": [ [ "ProjectId", "The project id for the Dynamics 365 for Finance \u0026 Operations project inside LCS", "", false, "false", "0" ], [ "ClientId", "The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal", "", false, "false", "" ], [ "BearerToken", "The token you want to use when working against the LCS api", "AccessToken,access_token", false, "true (ByPropertyName)", "" ], [ "ActiveTokenExpiresOn", "The point in time where the current bearer token will expire\nThe time is measured in Unix Time, total seconds since 1970-01-01", "expires_on", false, "true (ByPropertyName)", "0" ], [ "RefreshToken", "The Refresh Token that you want to use for the authentication process", "refresh_token", false, "true (ByPropertyName)", "" ], [ "LcsApiUri", "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\"", "resource", false, "true (ByPropertyName)", "https://lcsapi.lcs.dynamics.com" ], [ "Temporary", "Instruct the cmdlet to only temporarily override the persisted settings in the configuration storage", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Set the LCS configuration details", "Name": "Set-D365LcsApiConfig", "Links": null, "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.", "Syntax": "Set-D365LcsApiConfig [[-ProjectId] \u003cInt32\u003e] [[-ClientId] \u003cString\u003e] [[-BearerToken] \u003cString\u003e] [[-ActiveTokenExpiresOn] \u003cInt64\u003e] [[-RefreshToken] \u003cString\u003e] [[-LcsApiUri] \u003cString\u003e] [-Temporary] [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365NugetPath", "Description": "Update the path where the module will be looking for the nuget.exe executable", "Params": [ [ "Path", "Path to the nuget.exe", "", true, "false", "" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Set the path for nuget.exe", "Name": "Set-D365NugetPath", "Links": null, "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", "Syntax": "Set-D365NugetPath [-Path] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365OfflineAuthenticationAdminEmail", "Description": "Sets the registered offline administrator in the \"DynamicsDevConfig.xml\" file located in the default Package Directory", "Params": [ [ "Email", "The desired email address of the to be offline administrator", "", true, "false", "" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Sets the offline administrator e-mail", "Name": "Set-D365OfflineAuthenticationAdminEmail", "Links": null, "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\"", "Syntax": "Set-D365OfflineAuthenticationAdminEmail [-Email] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365RsatConfiguration", "Description": "Update different RSAT configuration values while using the tool", "Tags": [ "RSAT", "Testing", "Regression Suite Automation Test", "Regression", "Test", "Automation", "Configuration" ], "Params": [ [ "LogGenerationEnabled", "Will set the LogGeneration property\n$true will make RSAT start generating logs\r\n$false will stop RSAT from generating logs", "", false, "false", "False" ], [ "VerboseSnapshotsEnabled", "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", "", false, "false", "False" ], [ "AddOperatorFieldsToExcelValidationEnabled", "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", "", false, "false", "False" ], [ "RSATConfigFilename", "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", "", false, "false", "Microsoft.Dynamics.RegressionSuite.WpfApp.exe.config" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Set different RSAT configuration values", "Name": "Set-D365RsatConfiguration", "Links": null, "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.", "Syntax": "Set-D365RsatConfiguration [[-LogGenerationEnabled] \u003cBoolean\u003e] [[-VerboseSnapshotsEnabled] \u003cBoolean\u003e] [[-AddOperatorFieldsToExcelValidationEnabled] \u003cBoolean\u003e] [[-RSATConfigFilename] \u003cObject\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365RsatTier2Crypto", "Description": "Set the needed registry settings for when you are running RSAT against a Tier2+ environment", "Tags": [ "RSAT", "Testing", "Regression Suite Automation Test", "Regression", "Test", "Automation", "Configuration" ], "Params": [ ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Set the needed configuration to work on Tier2+ environments", "Name": "Set-D365RsatTier2Crypto", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eSet-D365RsatTier2Crypto\nThis will configure the registry to support RSAT against a Tier2+ environment.", "Syntax": "Set-D365RsatTier2Crypto [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365SDPCleanUp", "Description": "Sets the configured retention period before updates are deleted", "Params": [ [ "NumberOfDays", "Number of days that deployable software packages should remain on the server", "", false, "false", "30" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Set the cleanup retention period", "Name": "Set-D365SDPCleanUp", "Links": null, "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", "Syntax": "Set-D365SDPCleanUp [[-NumberOfDays] \u003cInt32\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365SqlPackagePath", "Description": "Update the path where the module will be looking for the SqlPackage.exe executable", "Params": [ [ "Path", "Path to the SqlPackage.exe", "", true, "false", "" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Set the path for SqlPackage.exe", "Name": "Set-D365SqlPackagePath", "Links": null, "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", "Syntax": "Set-D365SqlPackagePath [-Path] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365StartPage", "Description": "Function for setting the start page in internet explorer", "Params": [ [ "Name", "Name of the D365 Instance", "", true, "false", "" ], [ "Url", "URL of the D365 for Finance \u0026 Operations instance that you want to have as your start page", "", true, "true (ByPropertyName)", "" ] ], "Alias": "", "Author": "Rasmus Andersen (@ITRasmus)", "Synopsis": "Sets the start page in internet explorer", "Name": "Set-D365StartPage", "Links": null, "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\"", "Syntax": "Set-D365StartPage [-Name] \u003cString\u003e [\u003cCommonParameters\u003e]\nSet-D365StartPage [-Url] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365SysAdmin", "Description": "Set a user to sysadmin inside the SQL Server", "Params": [ [ "User", "The user that you want to make sysadmin\nMost be well formatted server\\user or domain\\user.\nDefault value is: machinename\\administrator", "", false, "false", "\"$env:computername\\administrator\"" ], [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ] ], "Alias": "", "Author": "Mötz Jensen (@splaxi)", "Synopsis": "Set a user to sysadmin", "Name": "Set-D365SysAdmin", "Links": null, "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", "Syntax": "Set-D365SysAdmin [[-User] \u003cString\u003e] [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365TraceParserFileSize", "Description": "Change the maximum file size that the TraceParser generates", "Params": [ [ "FileSizeInMB", "The maximum size that you want to allow the TraceParser file to grow to\nOriginal value inside the configuration is 1024 (MB)", "", true, "false", "" ], [ "Path", "The path to the TraceParser.config file that you want to edit\nThe default path is: \"\\AosService\\Webroot\\Services\\TraceParserService\\TraceParserService.config\"", "", false, "false", "(Join-Path $Script:AOSPath \"Services\\TraceParserService\\TraceParserService.config\")" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Configue a new maximum file size for the TraceParser", "Name": "Set-D365TraceParserFileSize", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eSet-D365TraceParserFileSize -FileSizeInMB 2048\nThis will configure the maximum TraceParser file to 2048 MB.", "Syntax": "Set-D365TraceParserFileSize [-FileSizeInMB] \u003cString\u003e [[-Path] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365WebConfigDatabase", "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", "Tags": [ "DEV", "Tier2", "DB", "Database", "Debug", "JIT", "LCS", "Azure DB" ], "Params": [ [ "DatabaseServer", "The name of the database server\nObtain when you request JIT (Just-in-Time) access through the LCS portal", "", true, "false", "" ], [ "DatabaseName", "The name of the database\nObtain when you request JIT (Just-in-Time) access through the LCS portal", "", true, "false", "" ], [ "SqlUser", "The login name for the SQL Server instance\nObtain when you request JIT (Just-in-Time) access through the LCS portal", "", true, "false", "" ], [ "SqlPwd", "The password for the SQL Server user\nObtain when you request JIT (Just-in-Time) access through the LCS portal", "", true, "false", "" ], [ "Path", "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", "", false, "false", "$(Join-Path -Path $Script:AOSPath -ChildPath $Script:WebConfig)" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Set the database connection details", "Name": "Set-D365WebConfigDatabase", "Links": null, "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.", "Syntax": "Set-D365WebConfigDatabase [-DatabaseServer] \u003cString\u003e [-DatabaseName] \u003cString\u003e [-SqlUser] \u003cString\u003e [-SqlPwd] \u003cString\u003e [[-Path] \u003cObject\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365WebServerType", "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.", "Params": [ [ "RuntimeHostType", "The type of web server you want to use.\nValid options are:\r\n\"IIS\"\r\n\"IISExpress\"", "", true, "true (ByValue, ByPropertyName)", "" ] ], "Alias": "", "Author": "Sander Holvoet (@smholvoet)", "Synopsis": "Set the web server type to be used to run the D365FO instance", "Name": "Set-D365WebServerType", "Links": null, "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.", "Syntax": "Set-D365WebServerType [-RuntimeHostType] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Set-D365WorkstationMode", "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", "Params": [ [ "Enabled", "$True enables the workstation mode while $false deactivated the workstation mode", "", true, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Set the Workstation mode", "Name": "Set-D365WorkstationMode", "Links": null, "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.", "Syntax": "Set-D365WorkstationMode [-Enabled] \u003cBoolean\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Start-D365Environment", "Description": "Can start all relevant services that is running in a D365FO environment", "Params": [ [ "ComputerName", "An array of computers that you want to start services on.", "", false, "false", "@($env:computername)" ], [ "All", "Set when you want to start all relevant services\nIncludes:\r\nAos\r\nBatch\r\nFinancial Reporter", "", false, "false", "True" ], [ "Aos", "Start the Aos (iis) service", "", false, "false", "False" ], [ "Batch", "Start the batch service", "", false, "false", "False" ], [ "FinancialReporter", "Start the financial reporter (Management Reporter 2012) service", "", false, "false", "False" ], [ "DMF", "Start the Data Management Framework service", "", false, "false", "False" ], [ "OnlyStartTypeAutomatic", "Instruct the cmdlet to filter out services that are set to manual start or disabled", "", false, "false", "False" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Cmdlet to start the different services in a Dynamics 365 Finance \u0026 Operations environment", "Name": "Start-D365Environment", "Links": null, "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.", "Syntax": "Start-D365Environment [[-ComputerName] \u003cString[]\u003e] [[-All]] [-OnlyStartTypeAutomatic] [-ShowOriginalProgress] [\u003cCommonParameters\u003e]\nStart-D365Environment [[-ComputerName] \u003cString[]\u003e] [[-Aos]] [[-Batch]] [[-FinancialReporter]] [[-DMF]] [-OnlyStartTypeAutomatic] [-ShowOriginalProgress] [\u003cCommonParameters\u003e]" }, { "CommandName": "Start-D365EnvironmentV2", "Description": "Can start all relevant services that is running in a D365FO environment", "Params": [ [ "All", "Set when you want to start all relevant services\nIncludes:\r\nAos\r\nBatch\r\nFinancial Reporter\r\nData Management Framework", "", false, "false", "True" ], [ "Aos", "Start the Aos (iis) service", "", false, "false", "False" ], [ "Batch", "Start the batch service", "", false, "false", "False" ], [ "FinancialReporter", "Start the financial reporter (Management Reporter 2012) service", "", false, "false", "False" ], [ "DMF", "Start the Data Management Framework service", "", false, "false", "False" ], [ "OnlyStartTypeAutomatic", "Instruct the cmdlet to filter out services that are set to manual start or disabled", "", false, "false", "False" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ] ], "Alias": "", "Author": "Vincent Verweij (@VincentVerweij)", "Synopsis": "Cmdlet to start the different services in a Dynamics 365 Finance \u0026 Operations environment", "Name": "Start-D365EnvironmentV2", "Links": null, "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.", "Syntax": "Start-D365EnvironmentV2 [[-All]] [-OnlyStartTypeAutomatic] [-ShowOriginalProgress] [\u003cCommonParameters\u003e]\nStart-D365EnvironmentV2 [[-Aos]] [[-Batch]] [[-FinancialReporter]] [[-DMF]] [-OnlyStartTypeAutomatic] [-ShowOriginalProgress] [\u003cCommonParameters\u003e]" }, { "CommandName": "Start-D365EventTrace", "Description": "Start an Event Trace session with default values to help you getting started", "Tags": [ "ETL", "EventTracing", "EventTrace" ], "Params": [ [ "ProviderName", "Name of the provider(s) you want to have part of your trace\nAccepts an array/list of provider names", "", true, "true (ByValue, ByPropertyName)", "" ], [ "OutputPath", "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\"", "", false, "false", "(Join-Path -Path $Script:DefaultTempPath -ChildPath \"EventTrace\")" ], [ "SessionName", "Name that you want the tracing session to have while running the trace\nDefault value is \"d365fo.tools.trace\"", "", false, "false", "d365fo.tools.trace" ], [ "FileName", "Name of the file that you want the trace to write its output to\nDefault value is \"d365fo.tools.trace.etl\"", "", false, "false", "d365fo.tools.trace.etl" ], [ "OutputFormat", "The desired output format of the ETL file being outputted from the tracing session\nDefault value is \"bincirc\"", "", false, "false", "bincirc" ], [ "MinBuffer", "The minimum buffer size in MB that you want the tracing session to work with\nDefault value is 10240", "", false, "false", "10240" ], [ "MaxBuffer", "The maximum buffer size in MB that you want the tracing session to work with\nDefault value is 10240", "", false, "false", "10240" ], [ "BufferSizeKB", "The buffer size in KB that you want the tracing session to work with\nDefault value is 1024", "", false, "false", "1024" ], [ "MaxLogFileSizeMB", "The maximum log file size in MB that you want the tracing session to work with\nDefault value is 4096", "", false, "false", "4096" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Start an Event Trace session", "Name": "Start-D365EventTrace", "Links": null, "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.", "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]" }, { "CommandName": "Stop-D365Environment", "Description": "Can stop all relevant services that is running in a D365FO environment", "Params": [ [ "ComputerName", "An array of computers that you want to stop services on.", "", false, "false", "@($env:computername)" ], [ "All", "Set when you want to stop all relevant services\nIncludes:\r\nAos\r\nBatch\r\nFinancial Reporter", "", false, "false", "True" ], [ "Aos", "Stop the Aos (iis) service", "", false, "false", "False" ], [ "Batch", "Stop the batch service", "", false, "false", "False" ], [ "FinancialReporter", "Start the financial reporter (Management Reporter 2012) service", "", false, "false", "False" ], [ "DMF", "Start the Data Management Framework service", "", false, "false", "False" ], [ "Kill", "Instructs the cmdlet to kill the service(s) that you want to stop", "", false, "false", "False" ], [ "ShowOriginalProgress", "Instruct the cmdlet to show the standard output in the console\nDefault is $false which will silence the standard output", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Cmdlet to stop the different services in a Dynamics 365 Finance \u0026 Operations environment", "Name": "Stop-D365Environment", "Links": null, "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.", "Syntax": "Stop-D365Environment [[-ComputerName] \u003cString[]\u003e] [[-All]] [[-Kill]] [[-ShowOriginalProgress]] [\u003cCommonParameters\u003e]\nStop-D365Environment [[-ComputerName] \u003cString[]\u003e] [[-Aos]] [[-Batch]] [[-FinancialReporter]] [[-DMF]] [[-Kill]] [[-ShowOriginalProgress]] [\u003cCommonParameters\u003e]" }, { "CommandName": "Stop-D365EventTrace", "Description": "Stop an Event Trace session that you have started earlier with the d365fo.tools", "Tags": [ "ETL", "EventTracing", "EventTrace" ], "Params": [ [ "SessionName", "Name of the tracing session that you want to stop\nDefault value is \"d365fo.tools.trace\"", "", false, "false", "d365fo.tools.trace" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Stop an Event Trace session", "Name": "Stop-D365EventTrace", "Links": null, "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.", "Syntax": "Stop-D365EventTrace [[-SessionName] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Switch-D365ActiveDatabase", "Description": "Switches the 2 databases. The Old wil be renamed _original", "Params": [ [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "DestinationDatabaseName", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "SourceDatabaseName", "The database that takes the DatabaseName\u0027s place", "NewDatabaseName", true, "false", "" ], [ "DestinationSuffix", "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", "", false, "false", "_original" ], [ "EnableException", "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", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Switches the 2 databases. The Old wil be renamed _original", "Name": "Switch-D365ActiveDatabase", "Links": null, "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.", "Syntax": "Switch-D365ActiveDatabase [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [-SourceDatabaseName] \u003cString\u003e [[-DestinationSuffix] \u003cString\u003e] [-EnableException] [\u003cCommonParameters\u003e]" }, { "CommandName": "Test-D365Command", "Description": "Analyze a function and it\u0027s parameters\n\nThe cmdlet / function is capable of validating a string input with function name and parameters", "Params": [ [ "CommandText", "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\"", "", true, "false", "" ], [ "Mode", "The operation mode of the cmdlet / function\nValid options are:\r\n- Validate\r\n- ShowParameters", "", true, "false", "" ], [ "SplatInput", "Pass in your hashtable that you use for your command execution and have it validated", "", false, "false", "" ], [ "ShowSplatStyleV1", "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", "", false, "false", "False" ], [ "ShowSplatStyleV2", "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", "", false, "false", "False" ], [ "IncludeHelp", "Switch to instruct the cmdlet / function to output a simple guide with the colors in it", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Validate or show parameter set details with colored output", "Name": "Test-D365Command", "Links": null, "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.", "Syntax": "Test-D365Command [-CommandText] \u003cString\u003e [-Mode] \u003cString\u003e [-SplatInput \u003cHashtable\u003e] [-ShowSplatStyleV1] [-ShowSplatStyleV2] [-IncludeHelp] [\u003cCommonParameters\u003e]" }, { "CommandName": "Test-D365DataverseConnection", "Description": "Invokes the built-in http communication endpount, that validates the connection between the D365FO environment and dataverse", "Params": [ [ "BinDir", "The path to the bin directory for the environment\nDefault path is the same as the aos service PackagesLocalDirectory\\bin", "", false, "false", "\"$Script:BinDir\\bin\"" ] ], "Alias": "", "Synopsis": "Test the dataverse connection", "Name": "Test-D365DataverseConnection", "Links": null, "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.", "Syntax": "Test-D365DataverseConnection [[-BinDir] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Test-D365EntraIntegration", "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", "Params": [ ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Test the Entra Id integration", "Name": "Test-D365EntraIntegration", "Links": null, "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", "Syntax": "Test-D365EntraIntegration [\u003cCommonParameters\u003e]" }, { "CommandName": "Test-D365FlightServiceCatalogId", "Description": "Test if the FlightingServiceCatalogID element exists in the web.config file used by D365FO", "Tags": [ "Flight", "Flighting" ], "Params": [ [ "AosServiceWebRootPath", "Path to the root folder where to locate the web.config file", "", false, "false", "$Script:AOSPath" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi))", "Synopsis": "Test if the FlightingServiceCatalogID is present and filled out", "Name": "Test-D365FlightServiceCatalogId", "Links": null, "Examples": "-------------------------- EXAMPLE 1 --------------------------\nPS C:\\\u003eTest-D365FlightServiceCatalogId\nThis will open the web.config and check if the FlightingServiceCatalogID element is present or not.", "Syntax": "Test-D365FlightServiceCatalogId [[-AosServiceWebRootPath] \u003cString\u003e] [\u003cCommonParameters\u003e]" }, { "CommandName": "Test-D365LabelIdIsValid", "Description": "This function will validate if a string is a valid \u0027Label Id\u0027 format.", "Params": [ [ "LabelId", "The LabelId string thay you want to validate", "", true, "false", "" ] ], "Alias": "", "Author": "Alex Kwitny (@AlexOnDAX)", "Synopsis": "Checks if a string is a valid \u0027Label Id\u0027 format", "Name": "Test-D365LabelIdIsValid", "Links": null, "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", "Syntax": "Test-D365LabelIdIsValid [-LabelId] \u003cString\u003e [\u003cCommonParameters\u003e]" }, { "CommandName": "Update-D365BacpacModelFileSingleTable", "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", "Tags": [ "Bacpac", "Servicing", "Data", "SqlPackage", "Import", "Table", "Troubleshooting" ], "Params": [ [ "Path", "Path to the bacpac file that you want to work against\nIt can also be a zip file", "File,ModelFile", false, "true (ByValue, ByPropertyName)", "" ], [ "Table", "Name of the table that you want to be kept inside the model file when the update is done", "", true, "false", "" ], [ "Schema", "Schema where the table that you want to work against exists\nThe default value is \"dbo\"", "", false, "false", "dbo" ], [ "OutputPath", "Path to where you want the updated bacpac model file to be saved\nDefault value is: \"c:\\temp\\d365fo.tools\"", "", false, "false", "$Script:DefaultTempPath" ], [ "Force", "Switch to instruct the cmdlet to overwrite the bacpac model file specified in the OutputPath", "", false, "false", "False" ] ], "Alias": "", "Author": "Mötz Jensen (@Splaxi)", "Synopsis": "Update the \"model.xml\" from the bacpac file to a single table", "Name": "Update-D365BacpacModelFileSingleTable", "Links": null, "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.", "Syntax": "Update-D365BacpacModelFileSingleTable [[-Path] \u003cString\u003e] [-Table] \u003cString\u003e [[-Schema] \u003cString\u003e] [[-OutputPath] \u003cString\u003e] [-Force] [\u003cCommonParameters\u003e]" }, { "CommandName": "Update-D365User", "Description": "Is capable of updating all the user details inside the UserInfo table to enable a user to sign in", "Params": [ [ "DatabaseServer", "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", "", false, "false", "$Script:DatabaseServer" ], [ "DatabaseName", "The name of the database", "", false, "false", "$Script:DatabaseName" ], [ "SqlUser", "The login name for the SQL Server instance", "", false, "false", "$Script:DatabaseUserName" ], [ "SqlPwd", "The password for the SQL Server user", "", false, "false", "$Script:DatabaseUserPassword" ], [ "Email", "The search string to select which user(s) should be updated.\nThe parameter supports wildcards. E.g. -Email \"*@contoso.com*\"", "", true, "true (ByPropertyName)", "" ], [ "Company", "The company the user should start in.", "", false, "false", "" ] ], "Alias": "", "Author": "Rasmus Andersen (@ITRasmus)", "Synopsis": "Updates the user details in the database", "Name": "Update-D365User", "Links": null, "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", "Syntax": "Update-D365User [[-DatabaseServer] \u003cString\u003e] [[-DatabaseName] \u003cString\u003e] [[-SqlUser] \u003cString\u003e] [[-SqlPwd] \u003cString\u003e] [-Email] \u003cString\u003e [[-Company] \u003cString\u003e] [\u003cCommonParameters\u003e]" } ] ================================================ FILE: d365fo.tools/bin/readme.md ================================================ # bin folder The bin folder exists to store binary data. And scripts related to the type system. This 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) For more information on Type Accelerators, see the help on Set-PSFTypeAlias ================================================ FILE: d365fo.tools/d365fo.tools.psd1 ================================================ @{ # Script module or binary module file associated with this manifest RootModule = 'd365fo.tools.psm1' # Version number of this module. ModuleVersion = '0.7.10' # ID used to uniquely identify this module GUID = '7c7b26d4-f764-4cb0-a692-459a0a689dbb' # Author of this module Author = 'Mötz Jensen & Rasmus Andersen' # Company or vendor of this module CompanyName = 'Essence Solutions' # Copyright statement for this module Copyright = '(c) 2018 Mötz Jensen & Rasmus Andersen. All rights reserved.' # Description of the functionality provided by this module Description = 'A set of tools that will assist you when working with Dynamics 365 Finance & Operations development / demo machines.' # Minimum version of the Windows PowerShell engine required by this module PowerShellVersion = '5.0' # Modules that must be imported into the global environment prior to importing # this module. # To enable the GitHub dependency graph, changes should be synchronized with # https://github.com/d365collaborative/d365fo.tools/blob/master/.github/workflows/dependencies.yml RequiredModules = @( @{ ModuleName = 'PSFramework'; ModuleVersion = '1.9.308' } , @{ ModuleName = 'Az.Storage'; ModuleVersion = '1.11.0' } , @{ ModuleName = 'PSOAuthHelper'; ModuleVersion = '0.3.0' } , @{ ModuleName = 'ImportExcel'; ModuleVersion = '7.1.0' } ) # Assemblies that must be loaded prior to importing this module # RequiredAssemblies = @('bin\d365fo.tools.dll') # Type files (.ps1xml) to be loaded when importing this module # TypesToProcess = @('xml\d365fo.tools.Types.ps1xml') # Format files (.ps1xml) to be loaded when importing this module FormatsToProcess = @('xml\d365fo.tools.Format.ps1xml') # Functions to export from this module FunctionsToExport = @( 'Add-D365AzureStorageConfig', 'Add-D365BroadcastMessageConfig', 'Add-D365ModuleToRemove', 'Add-D365RsatWifConfigAuthorityThumbprint', 'Add-D365WindowsDefenderRules', 'Backup-D365DevConfig', 'Backup-D365MetaDataDir', 'Backup-D365Runbook', 'Backup-D365WebConfig', 'Backup-D365WifConfig', 'Clear-D365ActiveBroadcastMessageConfig', 'Clear-D365BacpacObject', 'Clear-D365BacpacTableData', 'Clear-D365MonitorData', 'Clear-D365TempDbTables', 'ConvertTo-D365Dacpac', 'Disable-D365MaintenanceMode' 'Disable-D365SqlChangeTracking', 'Disable-D365User', 'Disable-D365Flight', 'Disable-D365Exception', 'Disable-D365IISPreload', 'Enable-D365Exception', 'Enable-D365MaintenanceMode', 'Enable-D365SqlChangeTracking', 'Enable-D365User', 'Enable-D365Flight', 'Enable-D365IISPreload', 'Export-D365BacpacModelFile', 'Export-D365Model', 'Export-D365SecurityDetails', 'Find-D365Command', 'Get-D365ActiveAzureStorageConfig', 'Get-D365ActiveBroadcastMessageConfig', 'Get-D365AOTObject', 'Get-D365AzureDevOpsNuget', 'Get-D365AzureStorageConfig', 'Get-D365AzureStorageFile', 'Get-D365AzureStorageUrl', 'Get-D365BacpacSqlOptions', 'Get-D365BacpacTable', 'Get-D365BroadcastMessage', 'Get-D365BroadcastMessageConfig', 'Get-D365ClickOnceTrustPrompt', 'Get-D365CompilerResult', 'Get-D365Database', 'Get-D365DatabaseAccess', 'Get-D365DecryptedWebConfig', 'Get-D365DefaultModelForNewProjects', 'Get-D365DotNetClass', 'Get-D365DotNetMethod', 'Get-D365Environment', 'Get-D365EnvironmentSettings', 'Get-D365EventTraceProvider', 'Get-D365ExternalIP', 'Get-D365Flight', 'Get-D365IISPreload', 'Get-D365JsonService', 'Get-D365InstalledHotfix', 'Get-D365InstalledPackage', 'Get-D365InstalledService', 'Get-D365InstanceName', 'Get-D365Label', 'Get-D365Language', 'Get-D365LabelFile', 'Get-D365LcsApiConfig', 'Get-D365LcsApiToken', 'Get-D365LcsAssetFile', 'Get-D365LcsSharedAssetFile', 'Get-D365LcsAssetValidationStatus', 'Get-D365LcsDatabaseBackups', 'Get-D365LcsDatabaseOperationStatus', 'Get-D365LcsDeploymentStatus', 'Get-D365LcsEnvironmentHistory', 'Get-D365LcsEnvironmentMetadata', 'Get-D365LcsEnvironmentRsatCertificate', 'Get-D365MaintenanceMode', 'Get-D365Model', 'Get-D365Module', 'Get-D365OfflineAuthenticationAdminEmail', 'Get-D365PackageBundleDetail', 'Get-D365PackageLabelResourceFile', 'Get-D365PackageLabelResources', 'Get-D365ProductInformation', 'Get-D365RsatCertificateThumbprint', 'Get-D365RsatPlaybackFile', 'Get-D365RsatSoapHostname', 'Get-D365Runbook', 'Get-D365RunbookId', 'Get-D365RunbookLogFile', 'Get-D365SDPCleanUp', 'Get-D365SDPDetails', 'Get-D365Table', 'Get-D365TableField', 'Get-D365TableSequence', 'Get-D365TablesInChangedTracking', 'Get-D365TfsUri', 'Get-D365TfsWorkspace', 'Get-D365Url', 'Get-D365User', 'Get-D365UserAuthenticationDetail', 'Get-D365VisualStudioCompilerResult', 'Get-D365WebServerType', 'Get-D365WindowsActivationStatus', 'Import-D365AadUser', 'Import-D365AadApplication', 'Import-D365Bacpac', 'Import-D365Dacpac', 'Import-D365Model', 'Import-D365ExternalUser', 'Import-D365RsatSelfServiceCertificates', 'Initialize-D365RsatCertificate', 'Install-D365SupportingSoftware', 'Invoke-D365AzCopyTransfer', 'Invoke-D365AzureDevOpsNugetPush', 'Invoke-D365AzureStorageDownload', 'Invoke-D365AzureStorageUpload', 'Invoke-D365CompilerResultAnalyzer', 'Invoke-D365DataFlush', 'Invoke-D365DbSync', 'Invoke-D365DbSyncPartial', 'Invoke-D365DbSyncModule', 'Invoke-D365GenerateReportAggregateDataEntity', 'Invoke-D365GenerateReportAggregateMeasure', 'Invoke-D365GenerateReportConfigKey', 'Invoke-D365GenerateReportConfigKeyGroup', 'Invoke-D365GenerateReportDataEntity', 'Invoke-D365GenerateReportDataEntityField', 'Invoke-D365GenerateReportKpi', 'Invoke-D365GenerateReportLicenseCode', 'Invoke-D365GenerateReportMenuItem', 'Invoke-D365GenerateReports', 'Invoke-D365GenerateReportSsrs', 'Invoke-D365GenerateReportTable', 'Invoke-D365GenerateReportWorkflowType' 'Invoke-D365InstallAzCopy', 'Invoke-D365InstallLicense', 'Invoke-D365InstallNuget', 'Invoke-D365InstallSqlPackage', 'Invoke-D365LcsApiRefreshToken', 'Invoke-D365LcsDatabaseExport', 'Invoke-D365LcsDatabaseRefresh', 'Invoke-D365LcsDeployment', 'Invoke-D365LcsEnvironmentStart', 'Invoke-D365LcsEnvironmentStop', 'Invoke-D365LcsUpload', 'Invoke-D365ModuleCompile', 'Invoke-D365ModuleLabelGeneration', 'Invoke-D365ModuleReportsCompile', 'Invoke-D365ModuleFullCompile', 'Invoke-D365ProcessModule' 'Invoke-D365ReArmWindows', 'Invoke-D365RunbookAnalyzer', 'Invoke-D365SDPInstall', 'Invoke-D365SDPInstallUDE', 'Invoke-D365SCDPBundleInstall', 'Invoke-D365SeleniumDownload', 'Invoke-D365SysFlushAodCache', 'Invoke-D365SysRunnerClass', 'Invoke-D365SqlScript', 'Invoke-D365VisualStudioCompilerResultAnalyzer', 'Invoke-D365WinRmCertificateRotation', 'Invoke-D365TableBrowser', 'Invoke-D365BestPractice', 'New-D365Bacpac', 'New-D365CAReport', 'New-D365EntraIntegration', 'New-D365ISVLicense', 'New-D365ModuleToRemove', 'New-D365TopologyFile', 'Publish-D365WebResources', 'Publish-D365SsrsReport', 'Register-D365AzureStorageConfig', 'Remove-D365LcsAssetFile', 'Remove-D365BroadcastMessageConfig', 'Remove-D365Database', 'Remove-D365Model', 'Remove-D365User', 'Rename-D365Instance', 'Rename-D365ComputerName', 'Repair-D365BacpacModelFile', 'Restart-D365Environment', 'Restore-D365DevConfig', 'Restore-D365WebConfig', 'Send-D365BroadcastMessage', 'Set-D365ActiveAzureStorageConfig', 'Set-D365ActiveBroadcastMessageConfig', 'Set-D365Admin', 'Set-D365AzCopyPath', 'Set-D365ClickOnceTrustPrompt', 'Set-D365DefaultModelForNewProjects', 'Set-D365FavoriteBookmark', 'Set-D365LcsApiConfig', 'Set-D365NugetPath', 'Set-D365OfflineAuthenticationAdminEmail', 'Set-D365RsatTier2Crypto', 'Set-D365RsatConfiguration', 'Set-D365SDPCleanUp', 'Set-D365StartPage', 'Set-D365SqlPackagePath', 'Set-D365SysAdmin', 'Set-D365WebConfigDatabase', 'Set-D365WebServerType', 'Set-D365TraceParserFileSize', 'Set-D365WorkstationMode', 'Set-D365FlightServiceCatalogId', 'Start-D365Environment', 'Start-D365EnvironmentV2', 'Start-D365EventTrace', 'Stop-D365Environment', 'Stop-D365EventTrace', 'Switch-D365ActiveDatabase', 'Test-D365Command', 'Test-D365DataverseConnection', 'Test-D365EntraIntegration', 'Test-D365FlightServiceCatalogId', 'Test-D365LabelIdIsValid', 'Update-D365BacpacModelFileSingleTable', 'Update-D365User' ) # Cmdlets to export from this module CmdletsToExport = '' # Variables to export from this module VariablesToExport = '' # Aliases to export from this module AliasesToExport = @( 'Initialize-D365TestAutomationCertificate' , 'Add-D365WIFConfigAuthorityThumbprint' , 'Invoke-D365SqlCmd' , 'Get-D365ModelFileFromBacpac' , 'Get-D365SqlOptionsFromBacpacModelFile' , 'Clear-D365TableDataFromBacpac' ) # List of all modules packaged with this module ModuleList = @() # List of all files packaged with this module FileList = @() # Private data to pass to the module specified in ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. PrivateData = @{ #Support for PowerShellGet galleries. PSData = @{ # Tags applied to this module. These help with module discovery in online galleries. Tags = @('d365fo', 'Dynamics365', 'D365', 'Finance&Operations', 'FinanceOperations', 'FinanceAndOperations', 'Dynamics365FO') # A URL to the license for this module. LicenseUri = "https://opensource.org/licenses/MIT" # A URL to the main website for this project. ProjectUri = 'https://github.com/d365collaborative/d365fo.tools' # A URL to an icon representing this module. # IconUri = '' # ReleaseNotes of this module # ReleaseNotes = '' # Indicates this is a pre-release/testing version of the module. IsPrerelease = 'True' ExternalModuleDependencies = @('PSDiagnostics') } # End of PSData hashtable } # End of PrivateData hashtable } ================================================ FILE: d365fo.tools/d365fo.tools.psm1 ================================================ $script:ModuleRoot = $PSScriptRoot $script:ModuleVersion = "0.7.10" # Detect whether at some level dotsourcing was enforced $script:doDotSource = Get-PSFConfigValue -FullName d365fo.tools.Import.DoDotSource -Fallback $false if ($d365fo.tools_dotsourcemodule) { $script:doDotSource = $true } <# Note on Resolve-Path: All paths are sent through Resolve-Path/Resolve-PSFPath in order to convert them to the correct path separator. This allows ignoring path separators throughout the import sequence, which could otherwise cause trouble depending on OS. Resolve-Path can only be used for paths that already exist, Resolve-PSFPath can accept that the last leaf my not exist. This is important when testing for paths. #> # Detect whether at some level loading individual module files, rather than the compiled module was enforced $importIndividualFiles = Get-PSFConfigValue -FullName d365fo.tools.Import.IndividualFiles -Fallback $false if ($d365fo.tools_importIndividualFiles) { $importIndividualFiles = $true } if (Test-Path (Resolve-PSFPath -Path "$($script:ModuleRoot)\..\.git" -SingleItem -NewChild)) { $importIndividualFiles = $true } if (-not (Test-Path (Resolve-PSFPath "$($script:ModuleRoot)\commands.ps1" -SingleItem -NewChild))) { $importIndividualFiles = $true } function Import-ModuleFile { <# .SYNOPSIS Loads files into the module on module import. .DESCRIPTION This helper function is used during module initialization. It should always be dotsourced itself, in order to proper function. This provides a central location to react to files being imported, if later desired .PARAMETER Path The path to the file to load .EXAMPLE PS C:\> . Import-ModuleFile -File $function.FullName Imports the file stored in $function according to import policy #> [CmdletBinding()] Param ( [string] $Path ) if ($doDotSource) { . (Resolve-Path $Path) } else { $ExecutionContext.InvokeCommand.InvokeScript($false, ([scriptblock]::Create([io.file]::ReadAllText((Resolve-Path $Path)))), $null, $null) } } if ($importIndividualFiles) { # Execute Preimport actions . Import-ModuleFile -Path "$ModuleRoot\internal\scripts\preimport.ps1" # Import all internal functions foreach ($function in (Get-ChildItem "$ModuleRoot\internal\functions" -Filter "*.ps1" -Recurse -ErrorAction Ignore)) { . Import-ModuleFile -Path $function.FullName } # Import all public functions foreach ($function in (Get-ChildItem "$ModuleRoot\functions" -Filter "*.ps1" -Recurse -ErrorAction Ignore)) { . Import-ModuleFile -Path $function.FullName } # Execute Postimport actions . Import-ModuleFile -Path "$ModuleRoot\internal\scripts\postimport.ps1" } else { if (Test-Path (Resolve-PSFPath "$($script:ModuleRoot)\resourcesBefore.ps1" -SingleItem -NewChild)) { . Import-ModuleFile -Path "$($script:ModuleRoot)\resourcesBefore.ps1" } . Import-ModuleFile -Path "$($script:ModuleRoot)\commands.ps1" if (Test-Path (Resolve-PSFPath "$($script:ModuleRoot)\resourcesAfter.ps1" -SingleItem -NewChild)) { . Import-ModuleFile -Path "$($script:ModuleRoot)\resourcesAfter.ps1" } } ================================================ FILE: d365fo.tools/en-us/about_Deployable_Packages.help.txt ================================================ TOPIC about_Deployable_Packages SHORT DESCRIPTION Describes the concept of deployable packages and how to work with them using the d365fo.tools. LONG DESCRIPTION "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." - Install deployable packages from the command line (https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/deployment/install-deployable-package) 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. 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: - SDP: short for Software Deployable Package - Runbook: A runbook is a xml file created during the install process. It defines all the steps that will be executed by the installer. - Topology: A topology is another xml file that defines the components of the D365FO environment. The runbook is created based on the topology. The following gives an overview of the available cmdlets. Further information for each cmdlet is available in its help. Invoke-D365SDPInstall The Invoke-D365SDPInstall cmdlet is the main command used to install a deployable package. New-D365TopologyFile 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. Get-D365InstalledService 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. Get-D365InstalledPackage Used to retrieve a list of packages available in a D365FO environment. Set-D365SDPCleanUp and Get-D365SDPCleanUp 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. Get-D365Runbook 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. Get-D365RunbookId Used to retrieve the id of a runbook from a runbook file. Invoke-D365RunbookAnalyzer Used to analyze the issues of a failed runbook. Get-D365RunbookLogFile Used to retrieve the log file from the installation folder of a package for specific installation step. Backup-D365Runbook Used to create a backup of a runbook file. KEYWORDS DeployablePackage, Runbook SEE ALSO 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) ================================================ FILE: d365fo.tools/en-us/about_d365fo.tools.help.txt ================================================ TOPIC about_d365fo.tools SHORT DESCRIPTION Explains how to use the d365fo.tools powershell module LONG DESCRIPTION KEYWORDS d365fo.tools ================================================ FILE: d365fo.tools/functions/add-d365azurestorageconfig.ps1 ================================================  <# .SYNOPSIS Save an Azure Storage Account config .DESCRIPTION Adds an Azure Storage Account config to the configuration store .PARAMETER Name The logical name of the Azure Storage Account you are about to registered in the configuration store .PARAMETER AccountId The account id for the Azure Storage Account you want to register in the configuration store .PARAMETER AccessToken The access token for the Azure Storage Account you want to register in the configuration store .PARAMETER SAS The SAS key that you have created for the storage account or blob container .PARAMETER Container The name of the blob container inside the Azure Storage Account you want to register in the configuration store .PARAMETER Temporary Instruct the cmdlet to only temporarily add the azure storage account configuration in the configuration store .PARAMETER Force Switch to instruct the cmdlet to overwrite already registered Azure Storage Account entry .EXAMPLE PS C:\> Add-D365AzureStorageConfig -Name "UAT-Exports" -AccountId "1234" -AccessToken "dafdfasdfasdf" -Container "testblob" 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". .EXAMPLE PS C:\> Add-D365AzureStorageConfig -Name UAT-Exports -SAS "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" -AccountId "1234" -Container "testblob" 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". The SAS key enables you to provide explicit access to a given blob container inside an Azure Storage Account. The SAS key can easily be revoked and that way you have control over the access to the container and its content. .EXAMPLE PS C:\> Add-D365AzureStorageConfig -Name UAT-Exports -SAS "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" -AccountId "1234" -Container "testblob" -Temporary 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". The SAS key enables you to provide explicit access to a given blob container inside an Azure Storage Account. The SAS key can easily be revoked and that way you have control over the access to the container and its content. The configuration will only last for the rest of this PowerShell console session. .NOTES Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, Container Author: Mötz Jensen (@Splaxi) #> function Add-D365AzureStorageConfig { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $Name, [Parameter(Mandatory = $true)] [string] $AccountId, [Parameter(Mandatory = $true, ParameterSetName = "AccessToken")] [string] $AccessToken, [Parameter(Mandatory = $true, ParameterSetName = "SAS")] [string] $SAS, [Parameter(Mandatory = $true)] [Alias('Blob')] [Alias('Blobname')] [string] $Container, [switch] $Temporary, [switch] $Force ) $Details = @{AccountId = $AccountId.ToLower(); Container = $Container.ToLower(); } if ($PSCmdlet.ParameterSetName -eq "AccessToken") { $Details.AccessToken = $AccessToken } if ($PSCmdlet.ParameterSetName -eq "SAS") { if ($SAS.StartsWith("?")) { $SAS = $SAS.Substring(1) } $Details.SAS = $SAS } $Accounts = [hashtable](Get-PSFConfigValue -FullName "d365fo.tools.azure.storage.accounts") if ($Accounts.ContainsKey($Name)) { if ($Force) { $Accounts[$Name] = $Details Set-PSFConfig -FullName "d365fo.tools.azure.storage.accounts" -Value $Accounts } else { Write-PSFMessage -Level Host -Message "An Azure Storage Account with that name already exists. If you want to overwrite the already registered details please supply the -Force parameter." Stop-PSFFunction -Message "Stopping because an Azure Storage Account already exists with that name." return } } else { $null = $Accounts.Add($Name, $Details) Set-PSFConfig -FullName "d365fo.tools.azure.storage.accounts" -Value $Accounts } if (-not $Temporary) { Register-PSFConfig -FullName "d365fo.tools.azure.storage.accounts" -Scope UserDefault } } ================================================ FILE: d365fo.tools/functions/add-d365broadcastmessageconfig.ps1 ================================================  <# .SYNOPSIS Save a broadcast message config .DESCRIPTION Adds a broadcast message config to the configuration store .PARAMETER Name The logical name of the broadcast configuration you are about to register in the configuration store .PARAMETER Tenant Azure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to send a message to .PARAMETER URL URL / URI for the D365FO environment you want to send a message to .PARAMETER ClientId The ClientId obtained from the Azure Portal when you created a Registered Application .PARAMETER ClientSecret The ClientSecret obtained from the Azure Portal when you created a Registered Application .PARAMETER TimeZone Id of the Time Zone your environment is running in You might experience that the local VM running the D365FO is running another Time Zone than the computer you are running this cmdlet from All available .NET Time Zones can be traversed with tab for this parameter The default value is "UTC" .PARAMETER EndingInMinutes Specify how many minutes into the future you want this message / maintenance window to last Default value is 60 minutes 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. .PARAMETER OnPremise Specify if environnement is an D365 OnPremise Default value is "Not set" (= Cloud Environnement) .PARAMETER Temporary Instruct the cmdlet to only temporarily add the broadcast message configuration in the configuration store .PARAMETER Force Instruct the cmdlet to overwrite the broadcast message configuration with the same name .EXAMPLE 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" This will create a new broadcast message configuration with the name "UAT". It will save "e674da86-7ee5-40a7-b777-1111111111111" as the Azure Active Directory guid. It will save "https://usnconeboxax1aos.cloud.onebox.dynamics.com" as the D365FO environment. It will save "dea8d7a9-1602-4429-b138-111111111111" as the ClientId. It will save "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522" as ClientSecret. It will use the default value "UTC" Time Zone for converting the different time and dates. It will use the default end time which is 60 minutes. .EXAMPLE 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" This will create a new broadcast message configuration with the name "UAT". It will target an OnPremise environment. It will save "https://adfs.local/adfs" as the OAuth Tenant Provider. It will save "https://ax-sandbox.d365fo.local" as the D365FO environment. It will save "dea8d7a9-1602-4429-b138-111111111111" as the ClientId. It will save "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522" as ClientSecret. It will use the default value "UTC" Time Zone for converting the different time and dates. It will use the default end time which is 60 minutes. .NOTES Tags: Servicing, Broadcast, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret Author: Mötz Jensen (@Splaxi) .LINK Clear-D365ActiveBroadcastMessageConfig .LINK Get-D365ActiveBroadcastMessageConfig .LINK Get-D365BroadcastMessageConfig .LINK Remove-D365BroadcastMessageConfig .LINK Send-D365BroadcastMessage .LINK Set-D365ActiveBroadcastMessageConfig #> function Add-D365BroadcastMessageConfig { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $Name, [Alias('$AADGuid')] [string] $Tenant, [Alias('URI')] [string] $URL, [string] $ClientId, [string] $ClientSecret, [string] $TimeZone = "UTC", [int] $EndingInMinutes = 60, [switch] $OnPremise, [switch] $Temporary, [switch] $Force ) if (((Get-PSFConfig -FullName "d365fo.tools.broadcast.*.name").Value -contains $Name) -and (-not $Force)) { Write-PSFMessage -Level Host -Message "A broadcast message configuration with $Name as name already exists. If you want to overwrite the current configuration, please supply the -Force parameter." Stop-PSFFunction -Message "Stopping because a broadcast message configuration already exists with that name." return } $configName = "" #The ':keys' label is used to have a continue inside the switch statement itself :keys foreach ($key in $PSBoundParameters.Keys) { $configurationValue = $PSBoundParameters.Item($key) $configurationName = $key.ToLower() $fullConfigName = "" Write-PSFMessage -Level Verbose -Message "Working on $key with $configurationValue" -Target $configurationValue switch ($key) { "Name" { $configName = $Name.ToLower() $fullConfigName = "d365fo.tools.broadcast.$configName.name" } {"Temporary","Force" -contains $_} { continue keys } "TimeZone" { $timeZoneFound = Get-TimeZone -InputObject $TimeZone if (Test-PSFFunctionInterrupt) { return } $fullConfigName = "d365fo.tools.broadcast.$configName.$configurationName" $configurationValue = $timeZoneFound.Id } Default { $fullConfigName = "d365fo.tools.broadcast.$configName.$configurationName" } } Write-PSFMessage -Level Verbose -Message "Setting $fullConfigName to $configurationValue" -Target $configurationValue Set-PSFConfig -FullName $fullConfigName -Value $configurationValue if (-not $Temporary) { Register-PSFConfig -FullName $fullConfigName -Scope UserDefault } } } ================================================ FILE: d365fo.tools/functions/add-d365moduletoremove.ps1 ================================================  <# .SYNOPSIS Adds a ModuleToRemove.txt file to a deployable package .DESCRIPTION Modifies an existing deployable package and adds a ModuleToRemove.txt file to it. .PARAMETER ModuleToRemove Path to the ModuleToRemove.txt file that you want to have inside a deployable package .PARAMETER DeployablePackage Path to the deployable package file where the ModuleToRemove.txt file should be added .PARAMETER OutputPath Path where you want the generated deployable package to be stored Default value is the same as the "DeployablePackage" parameter .EXAMPLE PS C:\> Add-D365ModuleToRemove -ModuleToRemove "C:\temp\ModuleToRemove.txt" -DeployablePackage "C:\temp\DeployablePackage.zip" 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. .EXAMPLE PS C:\> New-D365ModuleToRemove -Path C:\Temp -Modules "MyRemovedModule1","MySecondRemovedModule" | Add-D365ModuleToRemove -DeployablePackage C:\Temp\DeployablePackage.zip 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. .LINK New-D365ModuleToRemove .NOTES Author: Florian Hopfner (@FH-Inway) #> function Add-D365ModuleToRemove { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter( Mandatory = $true, Position = 1, ValueFromPipelineByPropertyName = $true)] [string] $ModuleToRemove, [Parameter(Mandatory = $true, Position = 2)] [string] $DeployablePackage, [string] $OutputPath = $DeployablePackage ) begin { $oldprogressPreference = $global:progressPreference $global:progressPreference = 'silentlyContinue' } process { Add-FileToPackage -File $ModuleToRemove -Archive $DeployablePackage -Path "AosService\Scripts" -OutputPath $OutputPath } end { $global:progressPreference = $oldprogressPreference } } ================================================ FILE: d365fo.tools/functions/add-d365rsatwifconfigauthoritythumbprint.ps1 ================================================  <# .SYNOPSIS Add a certificate thumbprint to the wif.config. .DESCRIPTION Register a certificate thumbprint in the wif.config file. This can be useful for example when configuring RSAT on a local machine and add the used certificate thumbprint to that AOS.s .PARAMETER CertificateThumbprint The thumbprint value of the certificate that you want to register in the wif.config file .EXAMPLE PS C:\> Add-D365RsatWifConfigAuthorityThumbprint -CertificateThumbprint "12312323r424" This will open the wif.config file and insert the "12312323r424" thumbprint value into the file. .NOTES Tags: RSAT, Certificate, Testing, Regression Suite Automation Test, Regression, Test, Automation Author: Kenny Saelen (@kennysaelen) Author: Mötz Jensen (@Splaxi) #> function Add-D365RsatWifConfigAuthorityThumbprint { [Alias("Add-D365WIFConfigAuthorityThumbprint")] [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string]$CertificateThumbprint ) try { $wifConfigFile = Join-Path $script:ServiceDrive "\AOSService\webroot\wif.config" if($true -eq (Test-Path -Path $wifConfigFile)) { [xml]$wifXml = Get-Content $wifConfigFile $authorities = $wifXml.SelectNodes('//system.identityModel//identityConfiguration//securityTokenHandlers//securityTokenHandlerConfiguration//issuerNameRegistry//authority[@name="https://fakeacs.accesscontrol.windows.net/"]') if($authorities.Count -lt 1) { Write-PSFMessage -Level Critical -Message "Only one authority should be found with the name https://fakeacs.accesscontrol.windows.net/" Stop-PSFFunction -Message "Stopping because an invalid authority structure was found in the wif.config file." return } else { foreach ($authority in $authorities) { $addElem = $wifXml.CreateElement("add") $addAtt = $wifXml.CreateAttribute("thumbprint") $addAtt.Value = $CertificateThumbprint $addElem.Attributes.Append($addAtt) $authority.FirstChild.AppendChild($addElem) $wifXml.Save($wifConfigFile) } } } else { Write-PSFMessage -Level Critical -Message "The wif.config file would not be located on the system." Stop-PSFFunction -Message "Stopping because the wif.config file could not be located." return } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while configuring the certificates and the Windows Identity Foundation configuration for the AOS" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } } ================================================ FILE: d365fo.tools/functions/add-d365windowsdefenderrules.ps1 ================================================  <# .SYNOPSIS Add rules to Windows Defender to enhance performance during development. .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. 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. Supports rules for VS 2015 and VS 2019. .PARAMETER Silent Instruct the cmdlet to silence the output written to the console If set the output will be silenced, if not set, the output will be written to the console .EXAMPLE PS C:\> Add-D365WindowsDefenderRules This will add the most common rules to the Windows Defender as exceptions. All output will be written to the console. .EXAMPLE PS C:\> Add-D365WindowsDefenderRules -Silent This will add the most common rules to the Windows Defender as exceptions. All output will be silenced and not outputted to the console. .NOTES Tags: DevTools, Developer, Performance Author: Robin Kretzschmar (@darksmile92) Author: Mötz Jensen (@Splaxi) Author: Florian Hopfner (@FH-Inway) #> function Add-D365WindowsDefenderRules { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param ( [switch] $Silent ) $DefenderEnabled = Get-WindowsDefenderStatus -Silent:$Silent if ($DefenderEnabled -eq $false) { Write-PSFMessage -Level Host -Message "Windows Defender is not enabled on this machine." Stop-PSFFunction -Message "Stopping because of errors." return } try { $AOSServicePath = Join-Path $script:ServiceDrive "\AOSService" $AOSPath = Join-Path $script:ServiceDrive "\AOSService\webroot\bin" if (-not (Test-PathExists -Path $AOSServicePath -Type Container)) { return } # visual studio & tools Add-MpPreference -ExclusionProcess "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\devenv.exe" Add-MpPreference -ExclusionProcess "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\Extensions\TestPlatform\testhost.exe" Add-MpPreference -ExclusionProcess "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\devenv.exe" Add-MpPreference -ExclusionProcess "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\Extensions\TestPlatform\testhost.exe" Add-MpPreference -ExclusionProcess "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\devenv.exe" Add-MpPreference -ExclusionProcess "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\qtagent32_40.exe" Add-MpPreference -ExclusionProcess "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\Extensions\TestPlatform\testhost.exe" Add-MpPreference -ExclusionProcess "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" Add-MpPreference -ExclusionProcess "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe" Add-MpPreference -ExclusionProcess "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\qtagent32_40.exe" Add-MpPreference -ExclusionProcess "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\Extensions\TestPlatform\testhost.exe" Add-MpPreference -ExclusionProcess "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" Add-MpPreference -ExclusionProcess "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe" Add-MpPreference -ExclusionProcess "C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\devenv.exe" Add-MpPreference -ExclusionProcess "C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\qtagent32_40.exe" Add-MpPreference -ExclusionProcess "C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\Extensions\TestPlatform\testhost.exe" Add-MpPreference -ExclusionProcess "C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" Add-MpPreference -ExclusionProcess "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\devenv.exe" Add-MpPreference -ExclusionProcess "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\qtagent32_40.exe" Add-MpPreference -ExclusionProcess "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\Extensions\TestPlatform\testhost.exe" Add-MpPreference -ExclusionProcess "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe" Add-MpPreference -ExclusionProcess "C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" Add-MpPreference -ExclusionProcess "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe" Add-MpPreference -ExclusionProcess "C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" Add-MpPreference -ExclusionProcess "C:\Program Files\dotnet\dotnet.exe" # customize path for cloud machines Add-MpPreference -ExclusionProcess "$Script:BinDir\xppcAgent.exe" Add-MpPreference -ExclusionProcess "$Script:BinDir\SyncEngine.exe" Add-MpPreference -ExclusionProcess "$Script:BinDir\bin\LabelC.exe" Add-MpPreference -ExclusionProcess "$Script:BinDir\bin\SyncEngine.exe" Add-MpPreference -ExclusionProcess "$Script:BinDir\bin\xppbp.exe" Add-MpPreference -ExclusionProcess "$Script:BinDir\bin\xppc.dll" Add-MpPreference -ExclusionProcess "$Script:BinDir\bin\xppc.exe" Add-MpPreference -ExclusionProcess "$Script:BinDir\bin\xppcAgent.exe" Add-MpPreference -ExclusionProcess "$Script:BinDir\bin\xppcAgent.17.0.exe" Add-MpPreference -ExclusionProcess "$Script:BinDir\bin\xpppfagen.exe" Add-MpPreference -ExclusionProcess "$AOSPath\Batch.exe" Add-MpPreference -ExclusionProcess "$AOSPath\xppc.exe" Add-MpPreference -ExclusionProcess "$AOSPath\LabelC.exe" # add SQLServer Add-MpPreference -ExclusionProcess "C:\Program Files\Microsoft SQL Server\130\LocalDB\Binn\sqlservr.exe" Add-MpPreference -ExclusionProcess "C:\Program Files\Microsoft SQL Server\150\LocalDB\Binn\sqlservr.exe" Add-MpPreference -ExclusionProcess "C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Binn\sqlservr.exe" Add-MpPreference -ExclusionProcess "C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Binn\sqlservr.exe" # add IIS and IISExpress Add-MpPreference -ExclusionProcess "C:\Windows\System32\inetsrv\w3wp.exe" Add-MpPreference -ExclusionProcess "C:\Program Files\IIS Express\iisexpress.exe" # add Git Add-MpPreference -ExclusionProcess "C:\Program Files\Git\cmd\git.exe" #Compile kicks off the defender. Exclude base path to AOS helps on that. Add-MpPreference -ExclusionPath $AOSServicePath # cache folders Add-MpPreference -ExclusionPath "C:\Program Files (x86)\Microsoft Visual Studio 10.0" Add-MpPreference -ExclusionPath "C:\Program Files (x86)\Microsoft Visual Studio 14.0" Add-MpPreference -ExclusionPath "C:\Program Files (x86)\Microsoft Visual Studio" Add-MpPreference -ExclusionPath "C:\Program Files\Microsoft Visual Studio" Add-MpPreference -ExclusionPath "C:\Windows\assembly" Add-MpPreference -ExclusionPath "C:\Windows\Microsoft.NET" Add-MpPreference -ExclusionPath "C:\Program Files (x86)\MSBuild" Add-MpPreference -ExclusionPath "C:\Program Files\dotnet" Add-MpPreference -ExclusionPath "C:\Program Files (x86)\Microsoft SDKs" Add-MpPreference -ExclusionPath "C:\Program Files\Microsoft SDKs" Add-MpPreference -ExclusionPath "C:\Program Files (x86)\Common Files\Microsoft Shared\MSEnv" Add-MpPreference -ExclusionPath "C:\Program Files (x86)\Microsoft Office" # Trick to get the exclusion path to work Add-MpPreference -ExclusionPath $([System.Text.Encoding]::UTF8.GetString(([Convert]::FromBase64String("QzpcUHJvZ3JhbURhdGFcTWljcm9zb2Z0XFZpc3VhbFN0dWRpb1xQYWNrYWdlcw==")))) Add-MpPreference -ExclusionPath "C:\Program Files (x86)\Microsoft SDKs\NuGetPackages" Add-MpPreference -ExclusionPath "C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files" Add-MpPreference -ExclusionPath "C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files" Add-MpPreference -ExclusionPath "C:\Users\Administrator\AppData\Local\Microsoft\VisualStudio" Add-MpPreference -ExclusionPath "C:\Users\Administrator\AppData\Local\Microsoft\WebsiteCache" Add-MpPreference -ExclusionPath "C:\Users\Administrator\AppData\Roaming\Microsoft\VisualStudio" Add-MpPreference -ExclusionPath "$Env:USERPROFILE\AppData\Local\Microsoft\VisualStudio" Add-MpPreference -ExclusionPath "$Env:USERPROFILE\AppData\Local\Microsoft\WebsiteCache" Add-MpPreference -ExclusionPath "$Env:USERPROFILE\AppData\Roaming\Microsoft\VisualStudio" # Extensions Add-MpPreference -ExclusionExtension "md" Add-MpPreference -ExclusionExtension "man" Add-MpPreference -ExclusionExtension "xml" Add-MpPreference -ExclusionExtension "xpp" Add-MpPreference -ExclusionExtension "netmodule" } catch { Write-PSFMessage -Level Host -Message "Something went wrong while configuring Windows Defender rules." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } ================================================ FILE: d365fo.tools/functions/backup-d365devconfig.ps1 ================================================  <# .SYNOPSIS Backup the DynamicsDevConfig.xml file .DESCRIPTION Will backup the DynamicsDevConfig.xml file located in the PackagesLocalDirectory\Bin folder .PARAMETER OutputPath Path to the folder where you want the DynamicsDevConfig.xml file to be persisted Default is: "C:\Temp\d365fo.tools\DevConfigBackup" .PARAMETER Force Instructs the cmdlet to overwrite the destination file if it already exists .EXAMPLE PS C:\> Backup-D365DevConfig Will locate the DynamicsDevConfig.xml file, and back it up. It will look for the file in the PackagesLocalDirectory\Bin folder. E.g. K:\AosService\PackagesLocalDirectory\Bin\DynamicsDevConfig.xml. It will save the file to the default location: "C:\Temp\d365fo.tools\DevConfigBackup". A result set example: Filename LastModified File -------- ------------ ---- DynamicsDevConfig.xml 6/29/2021 7:31:04 PM C:\temp\d365fo.tools\DevConfigBackup\DynamicsDevConfig.xml .EXAMPLE PS C:\> Backup-D365DevConfig -Force Will locate the DynamicsDevConfig.xml file, back it up, and overwrite if a previous backup file exists. It will look for the file in the PackagesLocalDirectory\Bin folder. E.g. K:\AosService\PackagesLocalDirectory\Bin\DynamicsDevConfig.xml. It will save the file to the default location: "C:\Temp\d365fo.tools\DevConfigBackup". It will overwrite any file named DynamicsDevConfig.xml in the destination folder. A result set example: Filename LastModified File -------- ------------ ---- DynamicsDevConfig.xml 6/29/2021 7:31:04 PM C:\temp\d365fo.tools\DevConfigBackup\DynamicsDevConfig.xml .NOTES Tags: Web Server, IIS, IIS Express, Development Author: Sander Holvoet (@smholvoet) #> function Backup-D365DevConfig { [CmdletBinding()] [OutputType()] param ( [string] $OutputPath = $(Join-Path $Script:DefaultTempPath "DevConfigBackup"), [switch] $Force ) begin { if (-not (Test-PathExists -Path $OutputPath -Type Container -Create)) { return } $File = $(Join-Path -Path (Join-Path -Path $Script:PackageDirectory -ChildPath "bin") -ChildPath $Script:DevConfig) } process { if (-not (Test-PathExists -Path $File -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } Backup-File -File $File -DestinationPath $OutputPath -Force:$Force } } ================================================ FILE: d365fo.tools/functions/backup-d365metadatadir.ps1 ================================================  <# .SYNOPSIS Create a backup of the Metadata directory .DESCRIPTION Creates a backup of all the files and folders from the Metadata directory .PARAMETER MetaDataDir Path to the Metadata directory Default value is the PackagesLocalDirectory .PARAMETER BackupDir Path where you want the backup to be place .EXAMPLE PS C:\> Backup-D365MetaDataDir This will backup the PackagesLocalDirectory and create an PackagesLocalDirectory_backup next to it .NOTES Tags: PackagesLocalDirectory, MetaData, MetaDataDir, MeteDataDirectory, Backup, Development Author: Mötz Jensen (@Splaxi) #> function Backup-D365MetaDataDir { [CmdletBinding()] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )] [string] $MetaDataDir = "$Script:MetaDataDir", [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )] [string] $BackupDir = "$($Script:MetaDataDir)_backup" ) if (!(Test-Path -Path $MetaDataDir -Type Container)) { Write-PSFMessage -Level Host -Message "The $MetaDataDir path wasn't found. Please ensure the path exists and you have enough permission/c> to access the directory." Stop-PSFFunction -Message "Stopping because the path is missing." return } Invoke-TimeSignal -Start $Params = @($MetaDataDir, $BackupDir, "/MT:4", "/E", "/NFL", "/NDL", "/NJH", "/NC", "/NS", "/NP") #! We should consider to redirect the standard output & error like this: https://stackoverflow.com/questions/8761888/capturing-standard-out-and-error-with-start-process #Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly Start-Process -FilePath "Robocopy.exe" -ArgumentList $Params -NoNewWindow -Wait Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/backup-d365runbook.ps1 ================================================  <# .SYNOPSIS Backup a runbook file .DESCRIPTION Backup a runbook file for you to persist it for later analysis .PARAMETER File Path to the file you want to backup .PARAMETER DestinationPath Path to the folder where you want the backup file to be placed .PARAMETER Force Instructs the cmdlet to overwrite the destination file if it already exists .EXAMPLE PS C:\> Backup-D365Runbook -File "C:\DynamicsAX\InstallationRecords\Runbooks\Runbook_20190327.xml" This will backup the "C:\DynamicsAX\InstallationRecords\Runbooks\Runbook_20190327.xml". The default destination folder is used, "c:\temp\d365fo.tools\runbookbackups\". .EXAMPLE PS C:\> Backup-D365Runbook -File "C:\DynamicsAX\InstallationRecords\Runbooks\Runbook_20190327.xml" -Force This will backup the "C:\DynamicsAX\InstallationRecords\Runbooks\Runbook_20190327.xml". The default destination folder is used, "c:\temp\d365fo.tools\runbookbackups\". If the file already exists in the destination folder, it will be overwritten. .EXAMPLE PS C:\> Get-D365Runbook | Backup-D365Runbook This will backup all runbook files found with the "Get-D365Runbook" cmdlet. The default destination folder is used, "c:\temp\d365fo.tools\runbookbackups\". .NOTES Tags: Runbook, Backup, Analysis Author: Mötz Jensen (@Splaxi) #> function Backup-D365Runbook { [CmdletBinding()] [OutputType()] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('Path')] [string] $File, [string] $DestinationPath = $(Join-Path $Script:DefaultTempPath "RunbookBackups"), [switch] $Force ) begin { if (-not (Test-PathExists -Path $DestinationPath -Type Container -Create)) { return } } process { if (-not (Test-PathExists -Path $File -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } Backup-File -File $File -DestinationPath $DestinationPath -Force:$Force } } ================================================ FILE: d365fo.tools/functions/backup-d365webconfig.ps1 ================================================  <# .SYNOPSIS Backup the web.config file .DESCRIPTION Will backup the web.config file located in the AOS / IIS folder .PARAMETER OutputPath Path to the folder where you want the web.config file to be persisted Default is: "C:\Temp\d365fo.tools\WebConfigBackup" .PARAMETER Force Instructs the cmdlet to overwrite the destination file if it already exists .EXAMPLE PS C:\> Backup-D365WebConfig Will locate the web.config file, and back it up. It will look for the file in the AOS / IIS folder. E.g. K:\AosService\WebRoot\web.config. It will save the file to the default location: "C:\Temp\d365fo.tools\WebConfigBackup". A result set example: Filename LastModified File -------- ------------ ---- web.config 6/29/2021 7:31:04 PM C:\temp\d365fo.tools\WebConfigBackup\web.config .EXAMPLE PS C:\> Backup-D365WebConfig -Force Will locate the web.config file, back it up, and overwrite if a previous backup file exists. It will look for the file in the AOS / IIS folder. E.g. K:\AosService\WebRoot\web.config. It will save the file to the default location: "C:\Temp\d365fo.tools\WebConfigBackup". It will overwrite any file named web.config in the destination folder. A result set example: Filename LastModified File -------- ------------ ---- web.config 6/29/2021 7:31:04 PM C:\temp\d365fo.tools\WebConfigBackup\web.config .NOTES Tags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB Author: Mötz Jensen (@Splaxi) #> function Backup-D365WebConfig { [CmdletBinding()] [OutputType()] param ( [string] $OutputPath = $(Join-Path $Script:DefaultTempPath "WebConfigBackup"), [switch] $Force ) begin { if (-not (Test-PathExists -Path $OutputPath -Type Container -Create)) { return } $File = $(Join-Path -Path $Script:AOSPath -ChildPath $Script:WebConfig) } process { if (-not (Test-PathExists -Path $File -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } Backup-File -File $File -DestinationPath $OutputPath -Force:$Force } } ================================================ FILE: d365fo.tools/functions/backup-d365wifconfig.ps1 ================================================  <# .SYNOPSIS Backup the wif.config file .DESCRIPTION Will backup the wif.config file located in the AOS / IIS folder .PARAMETER OutputPath Path to the folder where you want the web.config file to be persisted Default is: "C:\Temp\d365fo.tools\WifConfigBackup" .PARAMETER Force Instructs the cmdlet to overwrite the destination file if it already exists .EXAMPLE PS C:\> Backup-D365WifConfig Will locate the wif.config file, and back it up. It will look for the file in the AOS / IIS folder. E.g. K:\AosService\WebRoot\wif.config. It will save the file to the default location: "C:\Temp\d365fo.tools\WifConfigBackup". A result set example: Filename LastModified File -------- ------------ ---- wif.config 6/29/2021 7:31:04 PM C:\temp\d365fo.tools\WifConfigBackup\wif.config .EXAMPLE PS C:\> Backup-D365WifConfig -Force Will locate the wif.config file, back it up, and overwrite if a previous backup file exists. It will look for the file in the AOS / IIS folder. E.g. K:\AosService\WebRoot\wif.config. It will save the file to the default location: "C:\Temp\d365fo.tools\WifConfigBackup". It will overwrite any file named wif.config in the destination folder. A result set example: Filename LastModified File -------- ------------ ---- wif.config 6/29/2021 7:31:04 PM C:\temp\d365fo.tools\WifConfigBackup\wif.config .NOTES Author: Florian Hopfner (@FH-Inway) #> function Backup-D365WifConfig { [CmdletBinding()] [OutputType()] param ( [string] $OutputPath = $(Join-Path $Script:DefaultTempPath "WifConfigBackup"), [switch] $Force ) begin { if (-not (Test-PathExists -Path $OutputPath -Type Container -Create)) { return } $File = $(Join-Path -Path $Script:AOSPath -ChildPath $Script:WifConfig) } process { if (-not (Test-PathExists -Path $File -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } Backup-File -File $File -DestinationPath $OutputPath -Force:$Force } } ================================================ FILE: d365fo.tools/functions/clear-d365activebroadcastmessageconfig.ps1 ================================================  <# .SYNOPSIS Clear the active broadcast message config .DESCRIPTION Clear the active broadcast message config from the configuration store .PARAMETER Temporary Instruct the cmdlet to only temporarily clear the active broadcast message configuration in the configuration store .EXAMPLE PS C:\> Clear-D365ActiveBroadcastMessageConfig This will clear the active broadcast message configuration from the configuration store. .NOTES Tags: Servicing, Broadcast, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret Author: Mötz Jensen (@Splaxi) .LINK Add-D365BroadcastMessageConfig .LINK Get-D365ActiveBroadcastMessageConfig .LINK Get-D365BroadcastMessageConfig .LINK Remove-D365BroadcastMessageConfig .LINK Send-D365BroadcastMessage .LINK Set-D365ActiveBroadcastMessageConfig #> function Clear-D365ActiveBroadcastMessageConfig { [CmdletBinding()] [OutputType()] param ( [switch] $Temporary ) $configurationName = "d365fo.tools.active.broadcast.message.config.name" Reset-PSFConfig -FullName $configurationName if (-not $Temporary) { Register-PSFConfig -FullName $configurationName -Scope UserDefault } } ================================================ FILE: d365fo.tools/functions/clear-d365bacpacobject.ps1 ================================================  <# .SYNOPSIS Clear out sql objects from inside the bacpac/dacpac or zip file .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 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 The default behavior is that you get a copy of the file, where the desired sql objects are removed .PARAMETER Path Path to the bacpac/dacpac or zip file that you want to work against .PARAMETER Name Name of the sql object that you want to remove Supports an array of names If a schema name isn't supplied as part of the table name, the cmdlet will prefix it with "dbo." Some sql objects are 3 part named, which will require that you fill them in with brackets E.g. [dbo].[SalesTable].[CustomIndexName1] - Index - Constraints .PARAMETER ObjectType Instruct the cmdlet, the type of object that you want to remove As we are manipulating the bacpac file, we can only handle 1 ObjectType per run If you want to remove SqlView and SqlIndex, you will have to run the cmdlet 1 time for SqlViews and 1 time for SqlIndex Supported types are: "SqlView", "SqlTable", "SqlIndex", "SqlCheckConstraint" .PARAMETER OutputPath Path to where you want the updated bacpac/dacpac or zip file to be saved .PARAMETER ClearFromSource Instruct the cmdlet to delete sql objects directly from the source file 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 .EXAMPLE PS C:\> Clear-D365BacpacObject -Path "C:\Temp\AxDB.bacpac" -ObjectType SqlView -Name "View2" -OutputPath "C:\Temp\AXBD_Cleaned.bacpac" This will remove the SqlView "View2" from inside the bacpac file. It uses "C:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "View2" as the name of the object to delete. It uses "C:\Temp\AXBD_Cleaned.bacpac" as the OutputPath to where it will store the updated bacpac file. .EXAMPLE PS C:\> Clear-D365BacpacObject -Path "C:\Temp\AxDB.bacpac" -ObjectType SqlView -Name "dbo.View1","View2" -OutputPath "C:\Temp\AXBD_Cleaned.bacpac" This will remove the SqlView(s) "dbo.View1" and "View2" from inside the bacpac file. It uses "C:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "dbo.View1","View2" as the names of objects to delete. It uses "C:\Temp\AXBD_Cleaned.bacpac" as the OutputPath to where it will store the updated bacpac file. .EXAMPLE PS C:\> Clear-D365BacpacObject -Path "C:\Temp\AxDB.bacpac" -ObjectType SqlIndex -Name "[dbo].[SalesTable].[CustomIndexName1]" -ClearFromSource This will remove the SqlIndex "CustomIndexName1" from the dbo.SalesTable table from inside the bacpac file. It uses "C:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "[dbo].[SalesTable].[CustomIndexName1]" as the name of the object to delete. Caution: 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. .NOTES It will NOT fail, if it can't find any object with the specified name #> function Clear-D365BacpacObject { [CmdletBinding(DefaultParameterSetName = "Copy")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')] param ( [Parameter(Mandatory = $true)] [Alias('File')] [Alias('BacpacFile')] [string] $Path, [Parameter(Mandatory = $true)] [Alias("ObjectName")] [string[]] $Name, [ValidateSet("SqlView", "SqlTable", "SqlIndex", "SqlCheckConstraint")] [string] $ObjectType, [Parameter(Mandatory = $true, ParameterSetName = "Copy")] [string] $OutputPath, [Parameter(Mandatory = $true, ParameterSetName = "Keep")] [switch] $ClearFromSource ) if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } $compressPath = "" if ($ClearFromSource) { $compressPath = $Path } else { $compressPath = $OutputPath if (-not (Test-PathExists -Path $compressPath -Type Leaf -ShouldNotExist)) { Write-PSFMessage -Level Host -Message "The $compressPath already exists. Consider changing the OutputPath or delete the $compressPath file." return } if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Copying the file from '$Path' to '$compressPath'" Copy-Item -Path $Path -Destination $compressPath Write-PSFMessage -Level Verbose -Message "Copying was completed." } Write-PSFMessage -Level Verbose -Message "Opening the file '$compressPath'." $file = [System.IO.File]::Open($compressPath, [System.IO.FileMode]::Open) $zipArch = [System.IO.Compression.ZipArchive]::new($file, [System.IO.Compression.ZipArchiveMode]::Update) Write-PSFMessage -Level Verbose -Message "File '$compressPath' was read succesfully." if (-not $zipArch) { $messageString = "Unable to open the file $compressPath." Write-PSFMessage -Level Host -Message $messageString Stop-PSFFunction -Message "Stopping because the file couldn't be opened." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) return } $pathWorkDirectory = "$([System.IO.Path]::GetTempPath())d365fo.tools\$([System.Guid]::NewGuid().Guid)" #Make sure the work path is created and available New-Item -Path $pathWorkDirectory -ItemType Directory -Force -ErrorAction Ignore > $null if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Building the regex patterns to look for in the model.xml file." # Build the array of regex patterns that we are looking for # Has to be the same type $searchCol = @( foreach ($item in $Name) { $fullObjectName = "" if (-not ($item -like "*.*")) { $fullObjectName = "[dbo].[$item]" } elseif ($item -like "*.*" -and (-not ($item -match '\[.*?\]\.\[.*?\]') )) { #Throw error name format isn't as expected Throw } else { $fullObjectName = $item } $regexName = $fullObjectName.Replace("[", "\[").Replace("]", "\]").Replace(".", "\.") '' -f $ObjectType, $regexName }) # The model files defines all objects that will be created when importing the bacpac file $model = $zipArch.GetEntry("model.xml") Write-PSFMessage -Level Verbose -Message "Extracting local model.xml file." # We will have a local "model.raw.xml" file to read from $pathModelRaw = Join-Path -Path $pathWorkDirectory -ChildPath "model.raw.xml" [System.IO.Compression.ZipFileExtensions]::ExtractToFile($model, $pathModelRaw) # We will have a local "model.xml" where we persist the changes to $pathModelWorking = Join-Path -Path $pathWorkDirectory -ChildPath "model.xml" # The Origin.xml file is a manifest file, with a checksum value for the model.xml file inside the bacpac # Removing a single character from the model.xml file, will invalidate the checksum stored inside the Origin.xml $origin = $zipArch.GetEntry("Origin.xml") Write-PSFMessage -Level Verbose -Message "Extracting local Origin.xml file." # We will have a local "Origin.raw.xml" file to read from $pathOriginRaw = Join-Path -Path $pathWorkDirectory -ChildPath "Origin.raw.xml" [System.IO.Compression.ZipFileExtensions]::ExtractToFile($origin, $pathOriginRaw) # We will have a local "Origin.xml" where we persist the changes to $pathOriginWorking = Join-Path -Path $pathWorkDirectory -ChildPath "Origin.xml" # The model file is a very large XML file, reading that into a DOM object will slow down the operation # We will be reading the file line-by-line $reader = [System.IO.StreamReader]::new($pathModelRaw) $writer = [System.IO.StreamWriter]::new($pathModelWorking) # We need to know when to skip lines and at what indent to stop skipping lines $skipLine = $false $skipIdent = -1 Write-PSFMessage -Level Verbose -Message "Starting the analysis of the model.xml file." :nextLine while ( -not $reader.EndOfStream) { $tmp = $reader.ReadLine() if ($skipLine) { # SkipLine indicates that we found the object that we want to remove # We need to search for the very first NEXT instance of "" if ($tmp -match "") { # We found a "", but there are several child elements if ($skipIdent -eq $tmp.IndexOf("<")) { Write-PSFMessage -Level Verbose -Message "Skipping lines disabled. Correct close element found." # The identication signals that we found the right "" # Resitting the search signal/variables $skipLine = $false $skipIdent = -1 continue nextLine } } # We need to move forward with reading the file continue nextLine } foreach ($regex in $searchCol) { # searchCol contains ALL regex patterns that we want to remove from the model file # This is done to increase performance, as we only read the file onces, but validates each line multiple times if (($tmp -match $regex)) { Write-PSFMessage -Level Verbose -Message "Regex: $regex had a match. Skipping lines until close element found." # A match indicates that we found the next object that we want to remove # Setting the signal/variables - identication helps later to match to the correct "" $skipIdent = $tmp.IndexOf("<") $skipLine = $true continue nextLine } } # If skipLine and no regex was hit, we need to line in the updated model.xml file $writer.WriteLine($tmp) } # This concludes the entire update on the model.xml file $reader.Close() $writer.Flush() $writer.Close() Write-PSFMessage -Level Verbose -Message "Calculating hash value (checksum) for the updated model.xml file." # The model file will be checksum validated when running an import of it # We need to handle that $hashValue = Get-FileHash -Path $pathModelWorking -Algorithm SHA256 | Select-Object -ExpandProperty Hash # Loading the Origin.xml into memory [xml]$xmlDoc = Get-Content -Path $pathOriginRaw Write-PSFMessage -Level Verbose -Message "Updating the hash value (checksum) inside the Origin.xml file." # Updating the hash vaule (checksum) and saving it $xmlDoc.DacOrigin.Checksums.Checksum.InnerText = $hashValue $xmlDoc.Save($pathOriginWorking) Write-PSFMessage -Level Verbose -Message "Switching out the Origin.xml and model.xml files from inside the bacpac." # We need to remove the model.xml and origin.xml from the bacpac (archive) $model.Delete() $origin.Delete() [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipArch, $pathModelWorking, "model.xml") > $null [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipArch, $pathOriginWorking, "Origin.xml") > $null $res = @{ } if ($zipArch) { $zipArch.Dispose() } if ($file) { $file.Close() $file.Dispose() } if (Test-PSFFunctionInterrupt) { return } $res.File = $compressPath $res.Filename = $(Split-Path -Path $compressPath -Leaf) [PSCustomObject]$res } ================================================ FILE: d365fo.tools/functions/clear-d365bacpactabledata.ps1 ================================================  <# .SYNOPSIS Clear out data for a table inside the bacpac/dacpac or zip file .DESCRIPTION Remove all data for a table inside a bacpac/dacpac or zip file, before restoring it into your SQL Server / Azure SQL DB It will open the file as a zip archive, locate the desired table and remove the data that otherwise would have been loaded The default behavior is that you get a copy of the file, where the desired data is removed .PARAMETER Path Path to the bacpac/dacpac or zip file that you want to work against .PARAMETER Table Name of the table that you want to delete the data for Supports an array of table names If a schema name isn't supplied as part of the table name, the cmdlet will prefix it with "dbo." Supports wildcard searching e.g. "Sales*" will delete all "dbo.Sales*" tables in the bacpac file .PARAMETER OutputPath Path to where you want the updated bacpac/dacpac or zip file to be saved .PARAMETER ClearFromSource Instruct the cmdlet to delete tables directly from the source file 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 .EXAMPLE PS C:\> Clear-D365BacpacTableData -Path "C:\Temp\AxDB.bacpac" -Table "BATCHJOBHISTORY" -OutputPath "C:\Temp\AXBD_Cleaned.bacpac" This will remove the data from the BatchJobHistory table from inside the bacpac file. It uses "C:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "BATCHJOBHISTORY" as the Table to delete data from. It uses "C:\Temp\AXBD_Cleaned.bacpac" as the OutputPath to where it will store the updated bacpac file. .EXAMPLE PS C:\> Clear-D365BacpacTableData -Path "C:\Temp\AxDB.bacpac" -Table "dbo.BATCHHISTORY","BATCHJOBHISTORY" -OutputPath "C:\Temp\AXBD_Cleaned.bacpac" This will remove the data from the dbo.BatchHistory and BatchJobHistory table from inside the bacpac file. It uses "C:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "dbo.BATCHHISTORY","BATCHJOBHISTORY" as the Table to delete data from. It uses "C:\Temp\AXBD_Cleaned.bacpac" as the OutputPath to where it will store the updated bacpac file. .EXAMPLE PS C:\> Clear-D365BacpacTableData -Path "C:\Temp\AxDB.bacpac" -Table "dbo.BATCHHISTORY","BATCHJOBHISTORY" -ClearFromSource This will remove the data from the dbo.BatchHistory and BatchJobHistory table from inside the bacpac file. It uses "C:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "dbo.BATCHHISTORY","BATCHJOBHISTORY" as the Table to delete data from. Caution: 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. .EXAMPLE PS C:\> Clear-D365BacpacTableData -Path "C:\Temp\AxDB.bacpac" -Table "CustomTableNameThatDoesNotExists","BATCHJOBHISTORY" -OutputPath "C:\Temp\AXBD_Cleaned.bacpac" -ErrorAction SilentlyContinue This will remove the data from the BatchJobHistory table from inside the bacpac file. It uses "C:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "CustomTableNameThatDoesNotExists","BATCHJOBHISTORY" as the Table to delete data from. It respects the respects the ErrorAction "SilentlyContinue", and will continue removing tables from the bacpac file, even when some tables are missing. It uses "C:\Temp\AXBD_Cleaned.bacpac" as the OutputPath to where it will store the updated bacpac file. .NOTES Tags: Bacpac, Servicing, Data, Deletion, SqlPackage Author: Mötz Jensen (@Splaxi) #> function Clear-D365BacpacTableData { [Alias("Clear-D365TableDataFromBacpac")] [CmdletBinding(DefaultParameterSetName = "Copy")] param ( [Parameter(Mandatory = $true)] [Alias('File')] [Alias('BacpacFile')] [string] $Path, [Parameter(Mandatory = $true)] [Alias("TableName")] [string[]] $Table, [Parameter(Mandatory = $true, ParameterSetName = "Copy")] [string] $OutputPath, [Parameter(Mandatory = $true, ParameterSetName = "Keep")] [switch] $ClearFromSource ) begin { if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } $compressPath = "" if ($ClearFromSource) { $compressPath = $Path } else { $compressPath = $OutputPath if (-not (Test-PathExists -Path $compressPath -Type Leaf -ShouldNotExist)) { Write-PSFMessage -Level Host -Message "The $compressPath already exists. Consider changing the OutputPath or delete the $compressPath file." return } if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Copying the file from '$Path' to '$compressPath'" Copy-Item -Path $Path -Destination $compressPath Write-PSFMessage -Level Verbose -Message "Copying was completed." } Write-PSFMessage -Level Verbose -Message "Opening the file '$compressPath'." $file = [System.IO.File]::Open($compressPath, [System.IO.FileMode]::Open) $zipArch = [System.IO.Compression.ZipArchive]::new($file, [System.IO.Compression.ZipArchiveMode]::Update) Write-PSFMessage -Level Verbose -Message "File '$compressPath' was read succesfully." if (-not $zipArch) { $messageString = "Unable to open the file $compressPath." Write-PSFMessage -Level Host -Message $messageString Stop-PSFFunction -Message "Stopping because the file couldn't be opened." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) return } } process { if (Test-PSFFunctionInterrupt) { return } foreach ($item in $Table) { $fullTableName = "" if (-not ($item -like "*.*")) { $fullTableName = "dbo.$item" } else { $fullTableName = $item } Write-PSFMessage -Level Verbose -Message "Looking for $fullTableName." $entries = @($zipArch.Entries | Where-Object Fullname -like "Data/$fullTableName/*") if ($entries.Count -lt 1) { Write-PSFMessage -Level Host -Message "The $item wasn't found. Please ensure that the schema or name is correct." $parms = @{Message = "Stopping because table was not present." } if ($ErrorActionPreference -eq "SilentlyContinue") { $parms.WarningAction = $ErrorActionPreference $parms.ErrorAction = $null } Stop-PSFFunction @parms } else { for ($i = 0; $i -lt $entries.Count; $i++) { Write-PSFMessage -Level Verbose -Message "Removing $($entries[$i]) from the file." $entries[$i].delete() } } } } end { Write-PSFMessage -Level Verbose -Message "Search completed." $res = @{ } if ($zipArch) { Write-PSFMessage -Level Verbose -Message "Closing and saving the file." $zipArch.Dispose() } if ($file) { $file.Close() $file.Dispose() } if (Test-PSFFunctionInterrupt) { return } $res.File = $compressPath $res.Filename = $(Split-Path -Path $compressPath -Leaf) [PSCustomObject]$res } } ================================================ FILE: d365fo.tools/functions/clear-d365monitordata.ps1 ================================================  <# .SYNOPSIS Clear the monitoring data from a Dynamics 365 for Finance & Operations machine .DESCRIPTION Clear the monitoring data that is filling up the service drive on a Dynamics 365 for Finance & Operations .PARAMETER Path The path to where the monitoring data is located The default value is the "ServiceDrive" (j:\ | k:\) and the \MonAgentData\SingleAgent\Tables folder structure .EXAMPLE PS C:\> Clear-D365MonitorData This will delete all the files that are located in the default path on the machine. Some files might be locked by a process, but the cmdlet will attemp to delete all files. .NOTES Tags: Monitor, MonitorData, MonitorAgent, CleanUp, Servicing Author: Mötz Jensen (@Splaxi) #> function Clear-D365MonitorData { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Position = 1, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)] [string] $Path = (Join-Path $script:ServiceDrive "\MonAgentData\SingleAgent\Tables") ) process { Get-ChildItem -Path $Path | Remove-Item -Force -ErrorAction SilentlyContinue } } ================================================ FILE: d365fo.tools/functions/clear-d365tempdbtables.ps1 ================================================  <# .SYNOPSIS Cleanup TempDB tables in Microsoft Dynamics 365 for Finance and Operations environment .DESCRIPTION This will cleanup X days of TempDB tables The reason behind this process is that sp_updatestats takes significantly longer depending on the number of TempDB tables in the system .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER Days Temp tables older than this Days input will be dropped The default value is 7 (days) .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Clear-D365TempDbTables -Days 7 This will cleanup old tempdb tables. It will use 7 as the Days parameter. The remaining parameters will use their default values, which are provided by the tools. .LINK https://msdyn365fo.wordpress.com/2019/12/18/cleanup-tempdb-tables-in-a-msdyn365fo-sandbox-environment/ .LINK https://github.com/PaulHeisterkamp/d365fo.blog/blob/master/Tools/SQL/DropTempDBTables.sql .NOTES Author: Alex Kwitny (@AlexOnDAX) Author: Mötz Jensen (@Splaxi) This cmdlet is based on the findings from Paul Heisterkamp (@braul) See his blog for more info: https://msdyn365fo.wordpress.com/2019/12/18/cleanup-tempdb-tables-in-a-msdyn365fo-sandbox-environment/ #> function Clear-D365TempDbTables { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param ( [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword, [int] $Days = 7, [switch] $EnableException ) Invoke-TimeSignal -Start $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $Params = @{DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd; TrustedConnection = $UseTrustedConnection; } $sqlCommand = Get-SQLCommand @Params $commandText = (Get-Content "$script:ModuleRoot\internal\sql\clear-d365tempdbtables.sql") -join [Environment]::NewLine $commandText = $commandText.Replace('@Days', $Days) $sqlCommand.CommandText = $commandText try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $null = $sqlCommand.ExecuteNonQuery() } catch { $messageString = "Something went wrong while working against the database." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/convertto-d365dacpac.ps1 ================================================  <# .SYNOPSIS Convert bacpac file to dacpac .DESCRIPTION Convert bacpac file to dacpac It will extract the origin.xml file from the file, and set the false for the file to be valid to be used as a dacpac file .PARAMETER Path Path to the bacpac file that you want to work against It can also be a zip file .EXAMPLE PS C:\> ConvertTo-D365Dacpac -Path "C:\Temp\AxDB.bacpac" This will convert the bacpac file into a dacpac file. It will extract the origin.xml file, update it and apply it to the file. It will rename the file into a dacpac. The source file will be manipulated, so be careful to have an extra copy of the file. .NOTES Tags: Bacpac, Servicing, Data, SqlPackage, Dacpac, Table Author: Mötz Jensen (@Splaxi) #> function ConvertTo-D365Dacpac { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [Alias('File')] [Alias('BacpacFile')] [string] $Path ) begin { } process { } end { if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } $fileName = [System.IO.Path]::GetFileNameWithoutExtension($Path) $OutputPath = Join-Path -Path $([System.IO.Path]::GetTempPath()) -ChildPath "Origin.xml" if (Test-PSFFunctionInterrupt) { return } $file = [System.IO.File]::Open($Path, [System.IO.FileMode]::Open) $zipArch = [System.IO.Compression.ZipArchive]::new($file, [System.IO.Compression.ZipArchiveMode]::Update) $originEntry = $zipArch.GetEntry("Origin.xml") if (-not $originEntry) { $messageString = "Unable to find the Origin.xml file inside the archive. It would indicate the $Path isn't a valid bacpac or dacpac." Write-PSFMessage -Level Host -Message $messageString Stop-PSFFunction -Message "Stopping because Origin.xml wasn't found." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) } if (Test-PSFFunctionInterrupt) { return } [System.IO.Compression.ZipFileExtensions]::ExtractToFile($originEntry, $OutputPath, $true) $originEntry.delete() $content = Get-Content -Path $OutputPath -Raw $content = $content -replace "true", "false" $content | Out-File -FilePath $OutputPath -Encoding utf8 -Force [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($zipArch, $OutputPath, "Origin.xml") > $null if ($zipArch) { $zipArch.Dispose() } if ($file) { $file.Close() $file.Dispose() } Rename-Item -Path $Path -NewName "$($fileName).dacpac" [PSCustomObject]@{ File = $Path.Replace("bacpac", "dacpac") Filename = "$($fileName).dacpac" } } } ================================================ FILE: d365fo.tools/functions/disable-d365exception.ps1 ================================================  <# .SYNOPSIS Disables throwing of exceptions .DESCRIPTION Restore the default exception behavior of the module to not support throwing exceptions Useful when the default behavior was changed with Enable-D365Exception and the default behavior should be restored .EXAMPLE PS C:\>Disable-D365Exception This will restore the default behavior of the module to not support throwing exceptions. .NOTES Tags: Exception, Exceptions, Warning, Warnings Author: Florian Hopfner (@FH-Inway) .LINK Enable-D365Exception #> function Disable-D365Exception { [CmdletBinding()] param () Write-PSFMessage -Level Verbose -Message "Disabling exception across the entire module." -Target $configurationValue Set-PSFFeature -Name 'PSFramework.InheritEnableException' -Value $false -ModuleName "D365fo.tools" Set-PSFFeature -Name 'PSFramework.InheritEnableException' -Value $false -ModuleName "PSOAuthHelper" $PSDefaultParameterValues['*:EnableException'] = $false } ================================================ FILE: d365fo.tools/functions/disable-d365flight.ps1 ================================================  <# .SYNOPSIS Used to disable a flight .DESCRIPTION Provides a method for disabling a flight in D365FO. .PARAMETER FlightName Name of the flight to disable .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .EXAMPLE PS C:\> Disable-D365Flight -FlightName DMFEnableAllCompanyExport Disables the flight DMFEnableAllCompanyExport .LINK 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 .NOTES Tags: Flight, Flighting Author: Frank Hüther (@FrankHuether) The DataAccess.FlightingServiceCatalogID must already be set in the web.config file. At no circumstances can this cmdlet be used to enable a flight in a PROD environment. #> function Disable-D365Flight { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String] $FlightName, [Parameter(Mandatory = $false, Position = 2)] [string] $DatabaseServer = $Script:DatabaseServer, [Parameter(Mandatory = $false, Position = 3)] [string] $DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, Position = 4)] [string] $SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, Position = 5)] [string] $SqlPwd = $Script:DatabaseUserPassword ) try { $WebConfigFile = join-Path -path $Script:AOSPath $Script:WebConfig Write-PSFMessage -Level Verbose -Message "Retrieve the FlightingServiceCatalogID" -Target $WebConfigFile $FlightServiceNode = Select-Xml -XPath "/configuration/appSettings/add[@key='DataAccess.FlightingServiceCatalogID']/@value" -Path $WebConfigFile $FlightServiceId = $FlightServiceNode.Node.Value Write-PSFMessage -Level Verbose -Message "FlightingServiceCatalogID: $FlightServiceId" -Target $WebConfigFile } catch { Write-PSFMessage -Level Host -Message "Something went wrong while reading from the web.config file" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } if ($null -eq $FlightServiceId) { 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" Stop-PSFFunction -Message "Stopping because of errors" return } $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\disable-flight.sql") -join [Environment]::NewLine try { $sqlCommand.Connection.Open() Write-PSFMessage -Level Verbose -Message "Disabling flight: $FlightName" $null = $sqlCommand.Parameters.Add("@FlightName", $FlightName) $null = $sqlCommand.Parameters.Add("@FlightServiceId", $FlightServiceId) Write-PSFMessage -Level Verbose -Message "Disable the flight in database" Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $null = $sqlCommand.ExecuteNonQuery() Write-PSFMessage -Level Verbose -Message "Flight $FlightName disabled with service ID $FlightServiceId" } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } } ================================================ FILE: d365fo.tools/functions/disable-d365iispreload.ps1 ================================================  <# .SYNOPSIS Disables IIS Preload for the AOSService application pool and website. .DESCRIPTION Reverts IIS Preload settings for the AOSService application: - Sets Application Pool Start Mode to OnDemand - Sets Idle Time-out to 0 (default) - Disables Preload on the AOSService website - Sets doAppInitAfterRestart to false (if Application Initialization is installed) - Restores previous IIS Preload configuration from backup if available - Restores or removes the initializationPage property as appropriate - Uninstalls IIS Application Initialization feature if it was not installed in the backup .EXAMPLE PS C:\> Disable-D365IISPreload Disables IIS Preload for the AOSService application pool and website, restoring previous settings from backup if available. .NOTES Author: Florian Hopfner (FH-Inway) 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) Written with GitHub Copilot GPT-4.1, mostly in agent mode. See commits for prompts. .LINK Get-D365IISPreload .LINK Enable-D365IISPreload #> function Disable-D365IISPreload { [CmdletBinding()] param () if (-not (Get-Module -ListAvailable -Name WebAdministration)) { 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" return } Import-Module WebAdministration -ErrorAction Stop $appPool = "AOSService" $site = "AOSService" # Set default values first $startMode = 'OnDemand' $idleTimeout = [TimeSpan]::Zero $preloadEnabled = $false $doAppInitAfterRestart = 'False' $preloadPage = $null # Try to restore previous IIS Preload configuration from backup if available $backupDir = Join-Path $Script:DefaultTempPath "IISConfigBackup" $backupFile = $null if (Test-Path $backupDir) { $backupFiles = Get-ChildItem -Path $backupDir -Filter 'IISPreloadConfig.*.json' | Sort-Object LastWriteTime -Descending if ($backupFiles) { $backupFile = $backupFiles[0].FullName } } if ($backupFile) { Write-PSFMessage -Level Host -Message "Restoring IIS Preload configuration from backup: $backupFile" $preloadConfig = Get-Content $backupFile | ConvertFrom-Json if ($preloadConfig.StartMode) { $startMode = $preloadConfig.StartMode } if ($preloadConfig.IdleTimeout) { $idleTimeout = $preloadConfig.IdleTimeout } if ($null -ne $preloadConfig.PreloadEnabled) { $preloadEnabled = $preloadConfig.PreloadEnabled } if ($preloadConfig.DoAppInitAfterRestart) { $doAppInitAfterRestart = $preloadConfig.DoAppInitAfterRestart } if ($preloadConfig.PreloadPage) { $preloadPage = $preloadConfig.PreloadPage } # Uninstall IIS Application Initialization feature if it was not installed in the backup if ($preloadConfig.IISApplicationInitFeature -eq 'Not installed') { Write-PSFMessage -Level Host -Message "Uninstalling IIS Application Initialization feature (Web-AppInit) as per backup state." try { Uninstall-WindowsFeature -Name Web-AppInit -Confirm:$false | Out-Null } catch { Write-PSFMessage -Level Warning -Message "Failed to uninstall IIS Application Initialization feature. $_" } } } # Set Application Pool Start Mode and Idle Time-out $setAppPoolStartModeParams = @{ Path = "IIS:\AppPools\$appPool" Name = 'startMode' Value = $startMode } Write-PSFMessage -Level Verbose -Message "Setting Application Pool '$appPool' startMode to '$startMode'" Set-ItemProperty @setAppPoolStartModeParams $setAppPoolIdleTimeoutParams = @{ Path = "IIS:\AppPools\$appPool" Name = 'processModel.idleTimeout' Value = $idleTimeout } Write-PSFMessage -Level Verbose -Message "Setting Application Pool '$appPool' idleTimeout to '$idleTimeout'" Set-ItemProperty @setAppPoolIdleTimeoutParams $setSitePreloadParams = @{ Path = "IIS:\Sites\$site" Name = 'applicationDefaults.preloadEnabled' Value = $preloadEnabled } Write-PSFMessage -Level Verbose -Message "Setting Site '$site' applicationDefaults.preloadEnabled to '$preloadEnabled'" Set-ItemProperty @setSitePreloadParams try { $setDoAppInitParams = @{ pspath = "MACHINE/WEBROOT/APPHOST/$site" filter = 'system.webServer/applicationInitialization' name = 'doAppInitAfterRestart' value = $doAppInitAfterRestart ErrorAction = 'Stop' } Write-PSFMessage -Level Verbose -Message "Setting Site '$site' doAppInitAfterRestart to '$doAppInitAfterRestart'" Set-WebConfigurationProperty @setDoAppInitParams } catch { Write-PSFMessage -Level Verbose -Message "Application Initialization not installed or not available. Skipping doAppInitAfterRestart." } # Reset or remove initializationPage setting $getInitPagesParams = @{ pspath = 'MACHINE/WEBROOT/APPHOST' filter = 'system.webServer/applicationInitialization' name = '.' location = $site ErrorAction = 'Stop' } $initPages = Get-WebConfigurationProperty @getInitPagesParams if ($initPages -and $initPages.Collection -and $initPages.Collection.Count -gt 0) { $currentPreloadPage = $initPages.Collection[0].initializationPage } if ($currentPreloadPage) { if ($preloadPage -and $preloadPage -ne "Not configured" -and $preloadPage -ne "Not available") { try { Write-PSFMessage -Level Verbose -Message "Setting Site '$site' initializationPage to '$preloadPage'" $setInitPageParams = @{ pspath = "MACHINE/WEBROOT/APPHOST/$site" filter = 'system.webServer/applicationInitialization' name = '.' value = @{ initializationPage = $preloadPage } AtElement = @{ initializationPage = $currentPreloadPage } ErrorAction = 'Stop' } Set-WebConfigurationProperty @setInitPageParams } catch { Write-PSFMessage -Level Verbose -Message "Preload page $preloadPage cannot be set. Application Initialization may not be installed or not available. Skipping initializationPage." } } else { try { Write-PSFMessage -Level Verbose -Message "Removing initializationPage from Site '$site'" if ($currentPreloadPage) { $removeInitPageParams = @{ pspath = "MACHINE/WEBROOT/APPHOST/$site" filter = 'system.webServer/applicationInitialization' name = '.' AtElement = @{ initializationPage = $currentPreloadPage } ErrorAction = 'Stop' } Remove-WebConfigurationProperty @removeInitPageParams } } catch { Write-PSFMessage -Level Verbose -Message "Failed to remove initializationPage from Site '$site'. It may not exist." } } } Write-PSFMessage -Level Host -Message "IIS Preload disabled for $site." # Restart IIS service to apply changes try { Write-PSFMessage -Level Host -Message "Restarting IIS service (W3SVC) to apply changes..." Restart-Service -Name 'W3SVC' -Force -ErrorAction Stop Write-PSFMessage -Level Host -Message "IIS service restarted successfully." } catch { Write-PSFMessage -Level Warning -Message "Failed to restart IIS service (W3SVC): $_" } } ================================================ FILE: d365fo.tools/functions/disable-d365maintenancemode.ps1 ================================================  <# .SYNOPSIS Sets the environment back into operating state .DESCRIPTION Sets the Dynamics 365 environment back into operating / running state after it has been in maintenance mode. .PARAMETER MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable or SQL script and the needed parameters based on your selection .EXAMPLE PS C:\> Disable-D365MaintenanceMode 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. .EXAMPLE PS C:\> Disable-D365MaintenanceMode -ShowOriginalProgress 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. The output from stopping the services will be written to the console / host. The output from the "deployment" process will be written to the console / host. The output from starting the services will be written to the console / host. .NOTES Tags: MaintenanceMode, Maintenance, License, Configuration, Servicing Author: Mötz Jensen (@splaxi) Author: Tommy Skaue (@skaue) On VHD based environments with administrator privileges: The cmdlet wraps the execution of Microsoft.Dynamics.AX.Deployment.Setup.exe and parses the parameters needed. Without administrator privileges or on cloud hosted environments: Will stop all services, execute a SQL script and start all services. .LINK Enable-D365MaintenanceMode .LINK Get-D365MaintenanceMode #> function Disable-D365MaintenanceMode { [CmdletBinding()] param ( [string] $MetaDataDir = "$Script:MetaDataDir", [string] $BinDir = "$Script:BinDir", [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\MaintenanceMode"), [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) if ((Get-Process -Name "devenv" -ErrorAction SilentlyContinue).Count -gt 0) { Write-PSFMessage -Level Host -Message "It seems that you have a Visual Studio running. Please exit Visual Studio and run the cmdlet again." Stop-PSFFunction -Message "Stopping because of running Visual Studio." return } if (-not $OutputCommandOnly) { Stop-D365Environment -All -ShowOriginalProgress:$ShowOriginalProgress | Format-Table } if (-not ($Script:IsAdminRuntime) -or ($Script:EnvironmentType -eq [EnvironmentType]::AzureHostedTier1)) { Write-PSFMessage -Level Verbose -Message "Setting Maintenance Mode without using executable (which requires local admin)." $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $Params = @{ DatabaseServer = $DatabaseServer DatabaseName = $DatabaseName SqlUser = $SqlUser SqlPwd = $SqlPwd } if ($OutputCommandOnly) { $scriptContent = Get-content -Path $("$script:ModuleRoot\internal\sql\disable-maintenancemode.sql") -Raw 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." Write-PSFMessage -Level Host -Message "$scriptContent" } else { Invoke-D365SqlScript @Params -FilePath $("$script:ModuleRoot\internal\sql\disable-maintenancemode.sql") -TrustedConnection $UseTrustedConnection } } else { Write-PSFMessage -Level Verbose -Message "Setting Maintenance Mode using executable." $executable = Join-Path -Path $BinDir -ChildPath "bin\Microsoft.Dynamics.AX.Deployment.Setup.exe" if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return } if (-not (Test-PathExists -Path $executable -Type Leaf)) { return } $params = @("-isemulated", "true", "-sqluser", "$SqlUser", "-sqlpwd", "$SqlPwd", "-sqlserver", "$DatabaseServer", "-sqldatabase", "$DatabaseName", "-metadatadir", "$MetaDataDir", "-bindir", "$BinDir", "-setupmode", "maintenancemode", "-isinmaintenancemode", "false") Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath } if ($OutputCommandOnly) { return } Start-D365Environment -All -ShowOriginalProgress:$ShowOriginalProgress | Format-Table } ================================================ FILE: d365fo.tools/functions/disable-d365sqlchangetracking.ps1 ================================================  <# .SYNOPSIS Disable Change Tracking for the environment .DESCRIPTION Disables the SQL Server Change Tracking for the environments database and all tables inside the database .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Disable-D365SqlChangeTracking This will disable the Change Tracking on the Sql Server. .NOTES Tags: MaintenanceMode, Maintenance, License, Configuration, Servicing Author: Mötz Jensen (@splaxi) #> function Disable-D365SqlChangeTracking { [CmdletBinding()] param ( [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword, [switch] $EnableException ) Invoke-TimeSignal -Start $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $Params = @{DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd; TrustedConnection = $UseTrustedConnection; } $sqlCommand = Get-SQLCommand @Params $commandText = (Get-Content "$script:ModuleRoot\internal\sql\disable-changetracking.sql") -join [Environment]::NewLine $commandText = $commandText.Replace('@DATABASENAME', $DatabaseName) $sqlCommand.CommandText = $commandText try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $null = $sqlCommand.ExecuteNonQuery() } catch { $messageString = "Something went wrong while working against the database." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/disable-d365user.ps1 ================================================  <# .SYNOPSIS Disables the user in D365FO .DESCRIPTION Sets the enabled to 0 in the userinfo table. .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER Email The search string to select which user(s) should be disabled. The parameter supports wildcards. E.g. -Email "*@contoso.com*" .EXAMPLE PS C:\> Disable-D365User This will Disable all users for the environment .EXAMPLE PS C:\> Disable-D365User -Email "claire@contoso.com" This will Disable the user with the email address "claire@contoso.com" .EXAMPLE PS C:\> Disable-D365User -Email "*contoso.com" This will Disable all users that matches the search "*contoso.com" in their email address .NOTES Tags: User, Users, Security, Configuration, Permission Author: Mötz Jensen (@Splaxi) #> function Disable-D365User { [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 1)] [string]$DatabaseServer = $Script:DatabaseServer, [Parameter(Mandatory = $false, Position = 2)] [string]$DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, Position = 3)] [string]$SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, Position = 4)] [string]$SqlPwd = $Script:DatabaseUserPassword, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 5)] [string]$Email = "*" ) begin { Invoke-TimeSignal -Start $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection try { $sqlCommand.Connection.Open() } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } process { if (Test-PSFFunctionInterrupt) { return } $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\disable-user.sql") -join [Environment]::NewLine $null = $sqlCommand.Parameters.AddWithValue('@Email', $Email.Replace("*", "%")) try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $reader = $sqlCommand.ExecuteReader() $NumAffected = 0 while ($reader.Read() -eq $true) { Write-PSFMessage -Level Verbose -Message "User $($reader.GetString(0)), $($reader.GetString(1)), $($reader.GetString(2)) Updated" $NumAffected++ } $reader.Close() Write-PSFMessage -Level Verbose -Message "Users updated : $NumAffected" } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { $reader.close() $sqlCommand.Parameters.Clear() } } end { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/enable-d365exception.ps1 ================================================  <# .SYNOPSIS Enable exceptions to be thrown .DESCRIPTION Change the default exception behavior of the module to support throwing exceptions Useful when the module is used in an automated fashion, like inside Azure DevOps pipelines and large PowerShell scripts .EXAMPLE PS C:\>Enable-D365Exception This will for the rest of the current PowerShell session make sure that exceptions will be thrown. .NOTES Tags: Exception, Exceptions, Warning, Warnings Author: Mötz Jensen (@Splaxi) .LINK Disable-D365Exception #> function Enable-D365Exception { [CmdletBinding()] param () Write-PSFMessage -Level Verbose -Message "Enabling exception across the entire module." -Target $configurationValue Set-PSFFeature -Name 'PSFramework.InheritEnableException' -Value $true -ModuleName "D365fo.tools" Set-PSFFeature -Name 'PSFramework.InheritEnableException' -Value $true -ModuleName "PSOAuthHelper" $PSDefaultParameterValues['*:EnableException'] = $true } ================================================ FILE: d365fo.tools/functions/enable-d365flight.ps1 ================================================  <# .SYNOPSIS Used to enable a flight .DESCRIPTION Provides a method for enabling a flight in D365FO. .PARAMETER FlightName Name of the flight to enable .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .EXAMPLE PS C:\> Enable-D365Flight -FlightName DMFEnableAllCompanyExport Enables the flight DMFEnableAllCompanyExport .NOTES Tags: Flight, Flighting Author: Frank Hüther (@FrankHuether) The DataAccess.FlightingServiceCatalogID must already be set in the web.config file. 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 At no circumstances can this cmdlet be used to enable a flight in a PROD environment. #> function Enable-D365Flight { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [String] $FlightName, [Parameter(Mandatory = $false, Position = 2)] [string] $DatabaseServer = $Script:DatabaseServer, [Parameter(Mandatory = $false, Position = 3)] [string] $DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, Position = 4)] [string] $SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, Position = 5)] [string] $SqlPwd = $Script:DatabaseUserPassword ) try { $WebConfigFile = join-Path -path $Script:AOSPath $Script:WebConfig Write-PSFMessage -Level Verbose -Message "Retrieve the FlightingServiceCatalogID" -Target $WebConfigFile $FlightServiceNode = Select-Xml -XPath "/configuration/appSettings/add[@key='DataAccess.FlightingServiceCatalogID']/@value" -Path $WebConfigFile $FlightServiceId = $FlightServiceNode.Node.Value Write-PSFMessage -Level Verbose -Message "FlightingServiceCatalogID: $FlightServiceId" -Target $WebConfigFile } catch { Write-PSFMessage -Level Host -Message "Something went wrong while reading from the web.config file" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } if ($null -eq $FlightServiceId) { 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" Stop-PSFFunction -Message "Stopping because of errors" return } $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\enable-flight.sql") -join [Environment]::NewLine try { $sqlCommand.Connection.Open() Write-PSFMessage -Level Verbose -Message "Enabling flight: $FlightName" $null = $sqlCommand.Parameters.Add("@FlightName", $FlightName) $null = $sqlCommand.Parameters.Add("@FlightServiceId", $FlightServiceId) Write-PSFMessage -Level Verbose -Message "Enable the flight in database" Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $null = $sqlCommand.ExecuteNonQuery() Write-PSFMessage -Level Verbose -Message "Flight $FlightName enabled with service ID $FlightServiceId" } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } } ================================================ FILE: d365fo.tools/functions/enable-d365iispreload.ps1 ================================================  <# .SYNOPSIS Enables IIS Preload for the AOSService application pool and website. .DESCRIPTION Configures IIS to preload the AOSService application, improving startup time after X++ compile. - Sets Application Pool Start Mode to AlwaysRunning - Sets Idle Time-out to 0 - Enables Preload on the AOSService website - Sets doAppInitAfterRestart to true (if Application Initialization is installed) - Optionally sets the initializationPage to a custom base URL .PARAMETER BaseUrl The base URL to use for the initializationPage setting in IIS Application Initialization. If not provided, the function will attempt to determine the base URL automatically using Get-D365Url. Example: https://usnconeboxax1aos.cloud.onebox.dynamics.com .EXAMPLE PS C:\> Enable-D365IISPreload This will enable IIS Preload and set the initializationPage using the automatically detected base URL. .EXAMPLE PS C:\> Enable-D365IISPreload -BaseUrl "https://usnconeboxax1aos.cloud.onebox.dynamics.com" This will enable IIS Preload and set the initializationPage to https://usnconeboxax1aos.cloud.onebox.dynamics.com/?mi=DefaultDashboard .NOTES Author: Florian Hopfner (FH-Inway) 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) Written with GitHub Copilot GPT-4.1, mostly in agent mode. See commits for prompts. .LINK Get-D365IISPreload .LINK Disable-D365IISPreload #> function Enable-D365IISPreload { [CmdletBinding()] param ( [string]$BaseUrl = "" ) if (-not (Get-Module -ListAvailable -Name WebAdministration)) { 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" return } Import-Module WebAdministration -ErrorAction Stop # Backup IIS Preload configuration before making changes $backupDir = Join-Path $Script:DefaultTempPath "IISConfigBackup" if (-not (Test-Path $backupDir)) { New-Item -Path $backupDir -ItemType Directory | Out-Null } $timestamp = Get-Date -Format 'yyyyMMdd_HHmmss' $iisConfigBackupFile = Join-Path $backupDir ("IISPreloadConfig.$timestamp.json") $preloadConfig = Get-D365IISPreload | ConvertTo-Json -Depth 5 $preloadConfig | Out-File -FilePath $iisConfigBackupFile -Encoding UTF8 Write-PSFMessage -Level Host -Message "IIS Preload configuration backed up to $iisConfigBackupFile" # Ensure IIS Application Initialization feature is installed $iisAppInitFeature = Get-WindowsFeature -Name Web-AppInit -ErrorAction SilentlyContinue if (-not ($iisAppInitFeature -and $iisAppInitFeature.Installed)) { Write-PSFMessage -Level Host -Message "IIS Application Initialization (Web-AppInit) feature is not installed. Installing..." Install-WindowsFeature -Name Web-AppInit -IncludeAllSubFeature -IncludeManagementTools -ErrorAction Stop | Out-Null Write-PSFMessage -Level Host -Message "IIS Application Initialization feature installed." } $appPool = "AOSService" $site = "AOSService" # Set Application Pool to AlwaysRunning and Idle Time-out to 0 $setAppPoolStartModeParams = @{ Path = "IIS:\AppPools\$appPool" Name = 'startMode' Value = 'AlwaysRunning' } Write-PSFMessage -Level Verbose -Message "Setting Application Pool '$appPool' startMode to 'AlwaysRunning'" Set-ItemProperty @setAppPoolStartModeParams $setAppPoolIdleTimeoutParams = @{ Path = "IIS:\AppPools\$appPool" Name = 'processModel.idleTimeout' Value = ([TimeSpan]::Zero) } Write-PSFMessage -Level Verbose -Message "Setting Application Pool '$appPool' idleTimeout to '0'" Set-ItemProperty @setAppPoolIdleTimeoutParams # Enable Preload on the website $setSitePreloadParams = @{ Path = "IIS:\Sites\$site" Name = 'applicationDefaults.preloadEnabled' Value = $true } Write-PSFMessage -Level Verbose -Message "Setting Site '$site' applicationDefaults.preloadEnabled to 'True'" Set-ItemProperty @setSitePreloadParams if (-not $BaseUrl) { try { $baseUrlObj = Get-D365Url if ($baseUrlObj -and $baseUrlObj.Url) { $BaseUrl = $baseUrlObj.Url.TrimEnd('/') } } catch { Write-PSFMessage -Level Verbose -Message "Could not determine base URL using Get-D365Url. Defaulting to root." $BaseUrl = "" } } # Set the initializationPage for application initialization try { $initPage = if ($BaseUrl) { "$BaseUrl/?mi=DefaultDashboard" } else { "/?mi=DefaultDashboard" } Write-PSFMessage -Level Verbose -Message "Setting Site '$site' initializationPage to '$initPage'" $addInitPageParams = @{ pspath = "MACHINE/WEBROOT/APPHOST/$site" filter = 'system.webServer/applicationInitialization' name = '.' value = @{ initializationPage = $initPage } ErrorAction = 'Stop' } Add-WebConfigurationProperty @addInitPageParams } catch { Write-PSFMessage -Level Verbose -Message "Preload page $initPage cannot be set. Application Initialization may not be installed or not available. Skipping initializationPage." } # Try to set doAppInitAfterRestart if Application Initialization is installed try { $setDoAppInitParams = @{ pspath = "MACHINE/WEBROOT/APPHOST/$site" filter = 'system.webServer/applicationInitialization' name = 'doAppInitAfterRestart' value = 'True' ErrorAction = 'Stop' } Write-PSFMessage -Level Verbose -Message "Setting Site '$site' doAppInitAfterRestart to 'True'" Set-WebConfigurationProperty @setDoAppInitParams } catch { Write-PSFMessage -Level Verbose -Message "doAppInitAfterRestart cannot be set. Application Initialization may not be installed or not available. Skipping doAppInitAfterRestart." } Write-PSFMessage -Level Host -Message "IIS Preload enabled for $site." # Restart IIS service to apply changes try { Write-PSFMessage -Level Host -Message "Restarting IIS service (W3SVC) to apply preload settings..." Restart-Service -Name 'W3SVC' -Force -ErrorAction Stop Write-PSFMessage -Level Host -Message "IIS service restarted successfully." } catch { Write-PSFMessage -Level Warning -Message "Failed to restart IIS service (W3SVC): $_" } } ================================================ FILE: d365fo.tools/functions/enable-d365maintenancemode.ps1 ================================================  <# .SYNOPSIS Sets the environment into maintenance mode .DESCRIPTION Sets the Dynamics 365 environment into maintenance mode to enable the user to update the license configuration .PARAMETER MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable or SQL script and the needed parameters based on your selection .EXAMPLE PS C:\> Enable-D365MaintenanceMode 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. .EXAMPLE PS C:\> Enable-D365MaintenanceMode -ShowOriginalProgress 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. The output from stopping the services will be written to the console / host. The output from the "deployment" process will be written to the console / host. The output from starting the services will be written to the console / host. .NOTES Tags: MaintenanceMode, Maintenance, License, Configuration, Servicing Author: Mötz Jensen (@splaxi) Author: Tommy Skaue (@skaue) On VHD based environments with administrator privileges: The cmdlet wraps the execution of Microsoft.Dynamics.AX.Deployment.Setup.exe and parses the parameters needed. Without administrator privileges or on cloud hosted environments: Will stop all services, execute a SQL script and starts the AOS service (other services are not needed during maintenance mode). .LINK Get-D365MaintenanceMode .LINK Disable-D365MaintenanceMode #> function Enable-D365MaintenanceMode { [CmdletBinding()] param ( [string] $MetaDataDir = "$Script:MetaDataDir", [string] $BinDir = "$Script:BinDir", [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\MaintenanceMode"), [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) if ((Get-Process -Name "devenv" -ErrorAction SilentlyContinue).Count -gt 0) { Write-PSFMessage -Level Host -Message "It seems that you have a Visual Studio running. Please exit Visual Studio and run the cmdlet again." Stop-PSFFunction -Message "Stopping because of running Visual Studio." return } if (-not $OutputCommandOnly) { Stop-D365Environment -All -ShowOriginalProgress:$ShowOriginalProgress | Format-Table } if (-not ($Script:IsAdminRuntime) -or ($Script:EnvironmentType -eq [EnvironmentType]::AzureHostedTier1)) { Write-PSFMessage -Level Verbose -Message "Setting Maintenance Mode without using executable (which requires local admin)." $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $Params = @{ DatabaseServer = $DatabaseServer DatabaseName = $DatabaseName SqlUser = $SqlUser SqlPwd = $SqlPwd } if ($OutputCommandOnly) { $scriptContent = Get-content -Path $("$script:ModuleRoot\internal\sql\enable-maintenancemode.sql") -Raw 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." Write-PSFMessage -Level Host -Message "$scriptContent" } else { Invoke-D365SqlScript @Params -FilePath $("$script:ModuleRoot\internal\sql\enable-maintenancemode.sql") -TrustedConnection $UseTrustedConnection } } else { Write-PSFMessage -Level Verbose -Message "Setting Maintenance Mode using executable." $executable = Join-Path -Path $BinDir -ChildPath "bin\Microsoft.Dynamics.AX.Deployment.Setup.exe" if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return } if (-not (Test-PathExists -Path $executable -Type Leaf)) { return } $params = @("-isemulated", "true", "-sqluser", "$SqlUser", "-sqlpwd", "$SqlPwd", "-sqlserver", "$DatabaseServer", "-sqldatabase", "$DatabaseName", "-metadatadir", "$MetaDataDir", "-bindir", "$BinDir", "-setupmode", "maintenancemode", "-isinmaintenancemode", "true") Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath } if ($OutputCommandOnly) { return } Start-D365Environment -Aos -ShowOriginalProgress:$ShowOriginalProgress | Format-Table } ================================================ FILE: d365fo.tools/functions/enable-d365sqlchangetracking.ps1 ================================================  <# .SYNOPSIS Enable Change Tracking for the environment .DESCRIPTION Enable the SQL Server Change Tracking for the environments database It is a requirement for the Data Entities refresh to be able to complete correctly .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Enable-D365SqlChangeTracking This will enable the Change Tracking on the Sql Server. .NOTES Tags: MaintenanceMode, Maintenance, License, Configuration, Servicing Author: Mötz Jensen (@splaxi) #> function Enable-D365SqlChangeTracking { [CmdletBinding()] param ( [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword, [switch] $EnableException ) Invoke-TimeSignal -Start $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $Params = @{DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd; TrustedConnection = $UseTrustedConnection; } $sqlCommand = Get-SQLCommand @Params $commandText = (Get-Content "$script:ModuleRoot\internal\sql\enable-changetracking.sql") -join [Environment]::NewLine $commandText = $commandText.Replace('@DATABASENAME', $DatabaseName) $sqlCommand.CommandText = $commandText try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $null = $sqlCommand.ExecuteNonQuery() } catch { $messageString = "Something went wrong while working against the database." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/enable-d365user.ps1 ================================================  <# .SYNOPSIS Enables the user in D365FO .DESCRIPTION Sets the enabled to 1 in the userinfo table .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER Email The search string to select which user(s) should be enabled The parameter supports wildcards. E.g. -Email "*@contoso.com*" Default value is "*" to update all users .EXAMPLE PS C:\> Enable-D365User This will enable all users for the environment .EXAMPLE PS C:\> Enable-D365User -Email "claire@contoso.com" This will enable the user with the email address "claire@contoso.com" .EXAMPLE PS C:\> Enable-D365User -Email "*contoso.com" This will enable all users that matches the search "*contoso.com" in their email address .NOTES Tags: User, Users, Security, Configuration, Permission Author: Mötz Jensen #> function Enable-D365User { [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 1)] [string]$DatabaseServer = $Script:DatabaseServer, [Parameter(Mandatory = $false, Position = 2)] [string]$DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, Position = 3)] [string]$SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, Position = 4)] [string]$SqlPwd = $Script:DatabaseUserPassword, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 5)] [string]$Email = "*" ) begin { Invoke-TimeSignal -Start $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection try { $sqlCommand.Connection.Open() } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } process { if (Test-PSFFunctionInterrupt) { return } $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\enable-user.sql") -join [Environment]::NewLine $null = $sqlCommand.Parameters.AddWithValue('@Email', $Email.Replace("*", "%")) try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $reader = $sqlCommand.ExecuteReader() $NumAffected = 0 while ($reader.Read() -eq $true) { Write-PSFMessage -Level Verbose -Message "User $($reader.GetString(0)), $($reader.GetString(1)), $($reader.GetString(2)) Updated" $NumAffected++ } $reader.Close() Write-PSFMessage -Level Verbose -Message "Users updated : $NumAffected" } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { $reader.close() $sqlCommand.Parameters.Clear() } } end { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/export-d365bacpacmodelfile.ps1 ================================================  <# .SYNOPSIS Extract the "model.xml" from the bacpac file .DESCRIPTION Extract the "model.xml" file from inside the bacpac file 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 .PARAMETER Path Path to the bacpac file that you want to work against It can also be a zip file .PARAMETER OutputPath Path to where you want the updated bacpac file to be saved Default value is: "c:\temp\d365fo.tools" .PARAMETER Force Switch to instruct the cmdlet to overwrite the "model.xml" specified in the OutputPath .EXAMPLE PS C:\> Export-D365BacpacModelFile -Path "c:\Temp\AxDB.bacpac" This will extract the "model.xml" file from inside the bacpac file. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "c:\temp\d365fo.tools" as the OutputPath to where it will store the extracted "bacpac.model.xml" file. .EXAMPLE PS C:\> Export-D365BacpacModelFile -Path "c:\Temp\AxDB.bacpac" -OutputPath "c:\Temp\model.xml" -Force This will extract the "model.xml" file from inside the bacpac file. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "c:\Temp\model.xml" as the OutputPath to where it will store the extracted "model.xml" file. It will override the "c:\Temp\model.xml" if already present. .EXAMPLE PS C:\> Export-D365BacpacModelFile -Path "c:\Temp\AxDB.bacpac" | Get-D365BacpacSqlOptions This will display all the SQL Server options configured in the bacpac file. First it will export the bacpac.model.xml from the "c:\Temp\AxDB.bacpac" file, using the Export-D365BacpacModelFile function. The output from Export-D365BacpacModelFile will be piped into the Get-D365BacpacSqlOptions function. .NOTES Tags: Bacpac, Servicing, Data, SqlPackage, Sql Server Options, Collation Author: Mötz Jensen (@Splaxi) #> function Export-D365BacpacModelFile { [Alias("Get-D365ModelFileFromBacpac")] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [Alias('File')] [Alias('BacpacFile')] [string] $Path, [string] $OutputPath = $Script:DefaultTempPath, [switch] $Force ) begin { if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } if ($OutputPath -eq $Script:DefaultTempPath) { $OutputPath = Join-Path -Path $OutputPath -ChildPath "bacpac.model.xml" } Test-PathExists -Path $(Split-Path -Path $OutputPath -Parent) -Type Container -Create > $null if (Test-PSFFunctionInterrupt) { return } if (-not $Force) { if (-not (Test-PathExists -Path $OutputPath -Type Leaf -ShouldNotExist)) { Write-PSFMessage -Level Host -Message "The $OutputPath already exists. Consider changing the OutputPath or set the Force parameter to overwrite the file." Stop-PSFFunction -Message "Stopping because output path was already present." return } } if (Test-PSFFunctionInterrupt) { return } } end { if (Test-PSFFunctionInterrupt) { return } $file = [System.IO.File]::Open($Path, [System.IO.FileMode]::Open) $zipArch = [System.IO.Compression.ZipArchive]::new($file) $modelEntry = $zipArch.GetEntry("model.xml") if (-not $modelEntry) { $messageString = "Unable to find the model.xml file inside the archive. It would indicate the $Path isn't a valid bacpac or dacpac." Write-PSFMessage -Level Host -Message $messageString Stop-PSFFunction -Message "Stopping because model.xml wasn't found." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) } if (Test-PSFFunctionInterrupt) { return } [System.IO.Compression.ZipFileExtensions]::ExtractToFile($modelEntry, $OutputPath, $true) if ($zipArch) { $zipArch.Dispose() } if ($file) { $file.Close() $file.Dispose() } [PSCustomObject]@{ File = $OutputPath Filename = $(Split-Path -Path $OutputPath -Leaf) } } } ================================================ FILE: d365fo.tools/functions/export-d365model.ps1 ================================================  <# .SYNOPSIS Export a model from Dynamics 365 for Finance & Operations .DESCRIPTION Export a model from a Dynamics 365 for Finance & Operations environment .PARAMETER Path Path to the folder where you want to save the model file .PARAMETER Model Name of the model that you want to work against .PARAMETER Force Instruct the cmdlet to overwrite already existing file .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin Default value is fetched from the current configuration on the machine .PARAMETER MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory .PARAMETER LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .EXAMPLE PS C:\> Export-D365Model -Path c:\temp\d365fo.tools -Model CustomModelName This will export the "CustomModelName" model from the default PackagesLocalDirectory path. It export the model to the "c:\temp\d365fo.tools" location. .NOTES Tags: ModelUtil, Axmodel, Model, Export Author: Mötz Jensen (@Splaxi) #> function Export-D365Model { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [Alias('File')] [string] $Path, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('Modelname')] [string] $Model, [switch] $Force, [string] $BinDir = "$Script:PackageDirectory\bin", [string] $MetaDataDir = "$Script:MetaDataDir", [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ModelUtilExport"), [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) begin { Invoke-TimeSignal -Start if ($Path.EndsWith("\")) { $Path = $Path.Substring(0, $Path.Length - 1) } } process { if($Force){ Get-ChildItem -Path "$Path\$Model-*.axmodel" | Select-Object -First 1 | Remove-Item -Force -ErrorAction SilentlyContinue } Invoke-ModelUtil -Command "Export" -Path $Path -BinDir $BinDir -MetaDataDir $MetaDataDir -Model $Model -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath if (Test-PSFFunctionInterrupt) { return } $file = Get-ChildItem -Path "$Path\$Model-*.axmodel" | Select-Object -First 1 [PSCustomObject]@{ File = $file.FullName Filename = (Split-Path $file.FullName -Leaf) } } end { Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/export-d365securitydetails.ps1 ================================================  <# .SYNOPSIS Extract details from a User Interface Security file .DESCRIPTION Extracts and partitions the security details from an User Interface Security file into the same structure as AOT security files .PARAMETER FilePath Path to the User Interface Security XML file you want to work against .PARAMETER OutputDirectory Path to the folder where the cmdlet will output and structure the details from the file. The cmdlet will create a sub folder named like the input file. Default value is: "C:\temp\d365fo.tools\security-extraction" .EXAMPLE PS C:\> Export-D365SecurityDetails -FilePath C:\temp\d365fo.tools\SecurityDatabaseCustomizations.xml 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" .NOTES Tags: Security, Configuration, Permission, Development Author: Mötz Jensen (@splaxi) The work and design of this cmdlet is based on the findings by Alex Meyer (@alexmeyer_ITGuy). He wrote about his findings on his blog: https://alexdmeyer.com/2018/09/26/converting-d365fo-user-interface-security-customizations-export-to-aot-security-xml-files/ He published a github repository: https://github.com/ameyer505/D365FOSecurityConverter All credits goes to Alex Meyer #> function Export-D365SecurityDetails { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [Alias('Path')] [string]$FilePath, [Parameter(Mandatory = $false)] [Alias('Output')] [string]$OutputDirectory = "C:\temp\d365fo.tools\security-extraction" ) begin { } process { if (-not (Test-PathExists -Path $FilePath -Type Leaf)) { return } if (-not (Test-PathExists -Path $OutputDirectory -Type Container)) { return } [xml] $xdoc = Get-Content $FilePath $fileName = [System.IO.Path]::GetFileNameWithoutExtension($FilePath) $OutputDirectory = Join-Path $OutputDirectory $fileName Write-PSFMessage -Level Verbose -Message "Creating the output directory for the extraction" -Target $OutputDirectory $null = New-Item -Path $OutputDirectory -ItemType Directory -Force -ErrorAction SilentlyContinue Write-PSFMessage -Level Verbose -Message "Getting all the security objects." $secObjects = $xdoc.SelectNodes("/*/*/*/*/*[starts-with(name(),'AxSec')]") if ($secObjects.Count -gt 0) { Write-PSFMessage -Level Verbose -Message "Looping through all the security objects we found" foreach ( $secObject in $secObjects) { $secPath = Join-Path $OutputDirectory $secObject.LocalName $null = New-Item -Path $secPath -ItemType Directory -Force -ErrorAction SilentlyContinue $secObjectName = $secObject.Name if (-not ([string]::IsNullOrEmpty($secObjectName))) { $filePathOut = Join-Path $secPath $secObjectName $filePathOut += ".xml" Write-PSFMessage -Level Verbose -Message "Generating the output file: $filePathOut" -Target $filePathOut $secObject.OuterXml | Out-File $filePathOut } } } } end { } } ================================================ FILE: d365fo.tools/functions/find-d365command.ps1 ================================================ #ValidationTags#Messaging,FlowControl,Pipeline,CodeStyle# function Find-D365Command { <# .SYNOPSIS Finds d365fo.tools commands searching through the inline help text .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 .PARAMETER Tag Finds all commands tagged with this auto-populated tag .PARAMETER Author Finds all commands tagged with this author .PARAMETER MinimumVersion Finds all commands tagged with this auto-populated minimum version .PARAMETER MaximumVersion Finds all commands tagged with this auto-populated maximum version .PARAMETER Rebuild Rebuilds the index .PARAMETER Pattern Searches help for all commands in d365fo.tools for the specified pattern and displays all results .PARAMETER Confirm Confirms overwrite of index .PARAMETER WhatIf Displays what would happen if the command is run .PARAMETER EnableException By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message. This avoids overwhelming you with "sea of red" exceptions, but is inconvenient because it basically disables advanced scripting. Using this switch turns this "nice by default" feature off and enables you to catch exceptions with your own try/catch. .EXAMPLE PS C:\> Find-D365Command "snapshot" For lazy typers: finds all commands searching the entire help for "snapshot" .EXAMPLE PS C:\> Find-D365Command -Pattern "snapshot" For rigorous typers: finds all commands searching the entire help for "snapshot" .EXAMPLE PS C:\> Find-D365Command -Tag copy Finds all commands tagged with "copy" .EXAMPLE PS C:\> Find-D365Command -Tag copy,user Finds all commands tagged with BOTH "copy" and "user" .EXAMPLE PS C:\> Find-D365Command -Author Mötz Finds every command whose author contains "Mötz" .EXAMPLE PS C:\> Find-D365Command -Author Mötz -Tag copy Finds every command whose author contains "Mötz" and it tagged as "copy" .EXAMPLE PS C:\> Find-D365Command -Pattern snapshot -Rebuild Finds all commands searching the entire help for "snapshot", rebuilding the index (good for developers) .NOTES Tags: Find, Help, Command Author: Mötz Jensen (@Splaxi) License: MIT https://opensource.org/licenses/MIT This cmdlet / function is copy & paste implementation based on the Find-DbaCommand from the dbatools.io project Original author: Simone Bizzotto (@niphold) #> [CmdletBinding(SupportsShouldProcess = $true)] param ( [String]$Pattern, [String[]]$Tag, [String]$Author, [String]$MinimumVersion, [String]$MaximumVersion, [switch]$Rebuild, [Alias('Silent')] [switch]$EnableException ) begin { function Get-D365TrimmedString($Text) { return $Text.Trim() -replace '(\r\n){2,}', "`n" } $tagsRex = ([regex]'(?m)^[\s]{0,15}Tags:(.*)$') $authorRex = ([regex]'(?m)^[\s]{0,15}Author:(.*)$') $minverRex = ([regex]'(?m)^[\s]{0,15}MinimumVersion:(.*)$') $maxverRex = ([regex]'(?m)^[\s]{0,15}MaximumVersion:(.*)$') function Get-D365Help([String]$commandName) { $thishelp = Get-Help $commandName -Full $thebase = @{ } $thebase.CommandName = $commandName $thebase.Name = $thishelp.Name $alias = Get-Alias -Definition $commandName -ErrorAction SilentlyContinue $thebase.Alias = $alias.Name -Join ',' ## fetch the description $thebase.Description = $thishelp.Description.Text ## fetch examples $thebase.Examples = Get-D365TrimmedString -Text ($thishelp.Examples | Out-String -Width 200) ## fetch help link $thebase.Links = ($thishelp.relatedLinks).NavigationLink.Uri ## fetch the synopsis $thebase.Synopsis = $thishelp.Synopsis ## fetch the syntax $thebase.Syntax = Get-D365TrimmedString -Text ($thishelp.Syntax | Out-String -Width 600) ## store notes $as = $thishelp.AlertSet | Out-String -Width 600 ## fetch the tags $tags = $tagsrex.Match($as).Groups[1].Value if ($tags) { $thebase.Tags = $tags.Split(',').Trim() } ## fetch the author $author = $authorRex.Match($as).Groups[1].Value if ($author) { $thebase.Author = $author.Trim() } ## fetch MinimumVersion $MinimumVersion = $minverRex.Match($as).Groups[1].Value if ($MinimumVersion) { $thebase.MinimumVersion = $MinimumVersion.Trim() } ## fetch MaximumVersion $MaximumVersion = $maxverRex.Match($as).Groups[1].Value if ($MaximumVersion) { $thebase.MaximumVersion = $MaximumVersion.Trim() } ## fetch Parameters $parameters = $thishelp.parameters.parameter $command = Get-Command $commandName $params = @() foreach($p in $parameters) { $paramAlias = $command.parameters[$p.Name].Aliases $paramDescr = Get-D365TrimmedString -Text ($p.Description | Out-String -Width 200) $params += , @($p.Name, $paramDescr, ($paramAlias -Join ','), ($p.Required -eq $true), $p.PipelineInput, $p.DefaultValue) } $thebase.Params = $params [pscustomobject]$thebase } function Get-D365Index() { if ($Pscmdlet.ShouldProcess($dest, "Recreating index")) { $dbamodule = Get-Module -Name d365fo.tools $allCommands = $dbamodule.ExportedCommands.Values | Where-Object CommandType -EQ 'Function' $helpcoll = New-Object System.Collections.Generic.List[System.Object] foreach ($command in $allCommands) { $x = Get-D365Help "$command" $helpcoll.Add($x) } # $dest = Get-DbatoolsConfigValue -Name 'Path.TagCache' -Fallback "$(Resolve-Path $PSScriptRoot\..)\dbatools-index.json" $dest = "$moduleDirectory\bin\d365fo.tools-index.json" $helpcoll | ConvertTo-Json -Depth 4 | Out-File $dest -Encoding UTF8 } } $moduleDirectory = (Get-Module -Name d365fo.tools).ModuleBase } process { $Pattern = $Pattern.TrimEnd("s") $idxFile = "$moduleDirectory\bin\d365fo.tools-index.json" if (!(Test-Path $idxFile) -or $Rebuild) { Write-PSFMessage -Level Verbose -Message "Rebuilding index into $idxFile" $swRebuild = [system.diagnostics.stopwatch]::StartNew() Get-D365Index Write-PSFMessage -Level Verbose -Message "Rebuild done in $($swRebuild.ElapsedMilliseconds)ms" } $consolidated = Get-Content -Raw $idxFile | ConvertFrom-Json $result = $consolidated if ($Pattern.Length -gt 0) { $result = $result | Where-Object { $_.PsObject.Properties.Value -like "*$Pattern*" } } if ($Tag.Length -gt 0) { foreach ($t in $Tag) { $result = $result | Where-Object Tags -Contains $t } } if ($Author.Length -gt 0) { $result = $result | Where-Object Author -Like "*$Author*" } if ($MinimumVersion.Length -gt 0) { $result = $result | Where-Object MinimumVersion -GE $MinimumVersion } if ($MaximumVersion.Length -gt 0) { $result = $result | Where-Object MaximumVersion -LE $MaximumVersion } Select-DefaultView -InputObject $result -Property CommandName, Synopsis } } ================================================ FILE: d365fo.tools/functions/get-d365activeazurestorageconfig.ps1 ================================================  <# .SYNOPSIS Get active Azure Storage Account configuration .DESCRIPTION Get active Azure Storage Account configuration object from the configuration store .PARAMETER OutputAsPsCustomObject Instruct the cmdlet to return a PsCustomObject object .EXAMPLE PS C:\> Get-D365ActiveAzureStorageConfig This will get the active Azure Storage configuration. .EXAMPLE PS C:\> Get-D365ActiveAzureStorageConfig -OutputAsPsCustomObject This will get the active Azure Storage configuration. The object will be output as a PsCustomObject, for you to utilize across your scripts. .NOTES Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, Container Author: Mötz Jensen (@Splaxi) #> function Get-D365ActiveAzureStorageConfig { [CmdletBinding()] param ( [switch] $OutputAsPsCustomObject ) $res = Get-PSFConfigValue -FullName "d365fo.tools.active.azure.storage.account" if ($OutputAsPsCustomObject) { [PSCustomObject]$res } else { $res } } ================================================ FILE: d365fo.tools/functions/get-d365activebroadcastmessageconfig.ps1 ================================================  <# .SYNOPSIS Get active broadcast message configuration .DESCRIPTION Get active broadcast message configuration from the configuration store .PARAMETER OutputAsHashtable Instruct the cmdlet to return a hastable object .EXAMPLE PS C:\> Get-D365ActiveBroadcastMessageConfig This will get the active broadcast message configuration. .NOTES Tags: Servicing, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret Author: Mötz Jensen (@Splaxi) .LINK Add-D365BroadcastMessageConfig .LINK Clear-D365ActiveBroadcastMessageConfig .LINK Get-D365BroadcastMessageConfig .LINK Remove-D365BroadcastMessageConfig .LINK Send-D365BroadcastMessage .LINK Set-D365ActiveBroadcastMessageConfig #> function Get-D365ActiveBroadcastMessageConfig { [CmdletBinding()] [OutputType()] param ( [switch] $OutputAsHashtable ) $configName = (Get-PSFConfig -FullName "d365fo.tools.active.broadcast.message.config.name").Value if ($configName -eq "") { Write-PSFMessage -Level Host -Message "It looks like there isn't configured an active broadcast message configuration." Stop-PSFFunction -Message "Stopping because an active broadcast message configuration wasn't found." return } Get-D365BroadcastMessageConfig -Name $configName -OutputAsHashtable:$OutputAsHashtable } ================================================ FILE: d365fo.tools/functions/get-d365aotobject.ps1 ================================================  <# .SYNOPSIS Search for AOT object .DESCRIPTION Enables you to search for different AOT objects .PARAMETER Path Path to the package that you want to work against .PARAMETER ObjectType The type of AOT object you're searching for .PARAMETER Name Name of the object that you're looking for Accepts wildcards for searching. E.g. -Name "Work*status" Default value is "*" which will search for all objects .PARAMETER SearchInPackages Switch to instruct the cmdlet to search in packages directly instead of searching in the XppMetaData directory under a given package .PARAMETER IncludePath Switch to instruct the cmdlet to include the path for the object found .EXAMPLE PS C:\> Get-D365AOTObject -Name *flush* -ObjectType AxClass -Path "C:\AOSService\PackagesLocalDirectory\ApplicationFoundation" This will search inside the ApplicationFoundation package for all AxClasses that matches the search *flush*. .EXAMPLE PS C:\> Get-D365AOTObject -Name *flush* -ObjectType AxClass -IncludePath -Path "C:\AOSService\PackagesLocalDirectory\ApplicationFoundation" This will search inside the ApplicationFoundation package for all AxClasses that matches the search *flush* and include the full path to the files. .EXAMPLE PS C:\> Get-D365InstalledPackage -Name Application* | Get-D365AOTObject -Name *flush* -ObjectType AxClass 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*. .EXAMPLE PS C:\> Get-D365AOTObject -Path "C:\AOSService\PackagesLocalDirectory\*" -Name *flush* -ObjectType AxClass -SearchInPackages This is an advanced example and shouldn't be something you resolve to every time. This will search across all packages and will look for the all AxClasses that matches the search *flush*. It will NOT search in the XppMetaData directory for each package. This can stress your system. .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-D365AOTObject { [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('PackageDirectory')] [string] $Path, [ValidateSet('AxAggregateDataEntity', 'AxClass', 'AxCompositeDataEntityView', 'AxDataEntityView', 'AxForm', 'AxMap', 'AxQuery', 'AxTable', 'AxView')] [Alias('Type')] [string[]] $ObjectType = @("AxClass"), [string] $Name = "*", [switch] $SearchInPackages, [switch] $IncludePath ) begin { } process { $SearchList = New-Object -TypeName "System.Collections.ArrayList" foreach ($item in $ObjectType) { if ($SearchInPackages) { $SearchParent = Split-Path $Path -Leaf $null = $SearchList.Add((Join-Path "$Path" "\$SearchParent\$item\*.xml")) $SearchParent = $item #* Hack to make the logic when selecting the output work as expected } else { $SearchParent = "XppMetadata" $null = $SearchList.Add((Join-Path "$Path" "\$SearchParent\*\$item\*.xml")) } } #* We are searching files - so the last character has to be a * if($Name.Substring($Name.Length -1, 1) -ne "*") {$Name = "$Name*"} $Files = Get-ChildItem -Path ($SearchList.ToArray()) -Filter $Name if($IncludePath) { $Files | Select-PSFObject -TypeName "D365FO.TOOLS.AotObject" "BaseName as Name", @{Name = "AotType"; Expression = {Split-Path(Split-Path -Path $_.Fullname -Parent) -leaf }}, @{Name = "Model"; Expression = {Split-Path(($_.Fullname -Split $SearchParent)[0] ) -leaf }}, "Fullname as Path" } else { $Files | Select-PSFObject -TypeName "D365FO.TOOLS.AotObject" "BaseName as Name", @{Name = "AotType"; Expression = {Split-Path(Split-Path -Path $_.Fullname -Parent) -leaf }}, @{Name = "Model"; Expression = {Split-Path(($_.Fullname -Split $SearchParent)[0] ) -leaf }} } } end { } } ================================================ FILE: d365fo.tools/functions/get-d365azuredevopsnuget.ps1 ================================================  <# .SYNOPSIS Get Azure DevOps nugets .DESCRIPTION Get Azure DevOps nugets from a feed, to list all available details .PARAMETER Url The Azure DevOps url that you want to work against 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. .PARAMETER FeedName Name of the feed that you want to work against The feed name is found under the Artifacts area in Azure DevOps .PARAMETER PeronalAccessToken The Personal Access Token that you need to provide for the cmdlet to be able to communicate with the Azure DevOps REST services The Personal Access Token is configured via the Azure DevOps portal, on your own account .PARAMETER Name Name of the package / nuget that you are searching for Supports wildcard searching e.g. "*platform*" will output all packages / nugets that matches the search pattern Default value is "*" which will search for all packages / nugets .PARAMETER Latest Instruct the cmdlet to only fetch the latest package / nuget based on the version (highest) .EXAMPLE PS C:\> Get-D365AzureDevOpsNuget -Uri "https://dev.azure.com/Contoso/Financials" -FeedName "AASBuild365" -PeronalAccessToken "m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny" This will list all packages / nugets from the Azure DevOps feed. Foreach packacge, it will list all available versions. The http request will be going to the Uri "https://dev.azure.com/Contoso/Financials". The feed is identified by the FeedName "AASBuild365". The request will authenticate with the PeronalAccessToken "m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny" .EXAMPLE PS C:\> Get-D365AzureDevOpsNuget -Uri "https://dev.azure.com/Contoso/Financials" -FeedName "AASBuild365" -PeronalAccessToken "m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny" -Latest This will list all packages / nugets from the Azure DevOps feed. Foreach packacge, it will only list the latest version (highest). The http request will be going to the Uri "https://dev.azure.com/Contoso/Financials". The feed is identified by the FeedName "AASBuild365". The request will authenticate with the PeronalAccessToken "m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny" The cmdlet will only output the latest version by the Latest switch. .EXAMPLE PS C:\> $currentNugets = Get-D365AzureDevOpsNuget -Uri "https://dev.azure.com/Contoso/Financials" -FeedName "AASBuild365" -PeronalAccessToken "m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny" -Latest PS C:\> foreach ($item in $currentNugets) { PS C:\> $lcsNugets = Get-D365LcsAssetFile -FileType NuGetPackage -AssetFilename "$($item.Name)*" PS C:\> foreach ($itemInner in $lcsNugets) { PS C:\> if ($itemInner.FileName -Match "\d+\.\d+\.\d+\.\d+") { PS C:\> if ($([Version]$Matches[0]) -gt [Version]$item.Version) { PS C:\> $itemInner PS C:\> } PS C:\> } PS C:\> } PS C:\> } This will fetch all latest nugets from the Azure DevOps artifacts feed (nuget). For each nuget found, it will fetch matching nugets from the LCS Asset Library and return those that have a higher version. This can be used to automatically download and push the latest nuget from LCS to Azure DevOps. Needs to be put into work with Invoke-D365AzureDevOpsNugetPush .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-D365AzureDevOpsNuget { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [Alias('Uri')] [string] $Url, [Parameter(Mandatory = $true)] [string] $FeedName, [Parameter(Mandatory = $true)] [string] $PeronalAccessToken, [Alias('PackageName')] [string] $Name = "*", [switch] $Latest ) begin { if ($Url -notlike "https://dev.azure.com/*/*") { $messageString = "The supplied uri is not in a valid format. Please enter the project uri like https://dev.azure.com/[ORGANIZATION]]/[PROJECT]." Write-PSFMessage -Level Host -Message $messageString Stop-PSFFunction -Message "Stopping because the uri is wrongly formatted." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) return } else { $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" if ($Name -NotMatch '\*') { $uriPackages += "&packageNameQuery={1}" } $uriFeeds = $Url.Replace("https://dev.azure.com", "https://feeds.dev.azure.com") + "/_apis/packaging/Feeds?api-version=6.0-preview.1" } $header = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($PeronalAccessToken)")) } } process { if (Test-PSFFunctionInterrupt) { return } $feedsRaw = Invoke-RestMethod -Method Get -Uri $uriFeeds -Headers $header $feeds = @($feedsRaw | Select-Object -ExpandProperty Value) $feed = $feeds | Where-Object Name -like $FeedName | Select-Object -First 1 if (-not $feed) { $messageString = "No feed found that matched the provided feedname $feedname." Write-PSFMessage -Level Host -Message $messageString Stop-PSFFunction -Message "Stopping because the feed couldn't be located." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) return } $uriPackages = $uriPackages -f $($feed.Id), $Name $packagesRaw = Invoke-RestMethod -Method Get -Uri $uriPackages -Headers $header $packages = @($packagesRaw | Select-Object -ExpandProperty value) foreach ($item in $packages) { if ($item.Name -NotLike $Name) { continue } foreach ($itemInner in $item.versions) { if ($Latest) { if (-not $itemInner.IsLatest) { continue } } [PSCustomObject][ordered]@{ Name = $item.Name Version = [Version]$itemInner.Version VersionId = $itemInner.Id IsLatest = $itemInner.IsLatest PackageId = $item.Id PackageUrl = $item.Url } } } } end { } } ================================================ FILE: d365fo.tools/functions/get-d365azurestorageconfig.ps1 ================================================  <# .SYNOPSIS Get Azure Storage Account configs .DESCRIPTION Get all Azure Storage Account configuration objects from the configuration store .PARAMETER Name The name of the Azure Storage Account you are looking for Default value is "*" to display all Azure Storage Account configs .PARAMETER OutputAsHashtable Instruct the cmdlet to return a hastable object .EXAMPLE PS C:\> Get-D365AzureStorageConfig This will show all Azure Storage Account configs .EXAMPLE PS C:\> Get-D365AzureStorageConfig -OutputAsHashtable This will show all Azure Storage Account configs. Every object will be output as a hashtable, for you to utilize as parameters for other cmdlets. .NOTES Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, Container Author: Mötz Jensen (@Splaxi) #> function Get-D365AzureStorageConfig { [CmdletBinding()] param ( [string] $Name = "*", [switch] $OutputAsHashtable ) $StorageAccounts = [hashtable](Get-PSFConfigValue -FullName "d365fo.tools.azure.storage.accounts") foreach ($item in $StorageAccounts.Keys) { if ($item -NotLike $Name) { continue } $res = [ordered]@{Name = $item } $res += $StorageAccounts[$item] if ($OutputAsHashtable) { $res } else { [PSCustomObject]$res } } } ================================================ FILE: d365fo.tools/functions/get-d365azurestoragefile.ps1 ================================================  <# .SYNOPSIS Get file information from Azure Storage .DESCRIPTION Get information for files from an Azure Storage Account .PARAMETER AccountId Storage Account Name / Storage Account Id where file information should be retrieved from .PARAMETER AccessToken The token that has the needed permissions for the search action .PARAMETER SAS The SAS key for the storage account or blob container .PARAMETER Container Name of the blob container inside the storage account where file information should be retrieved from .PARAMETER Name Name of the files information should be retrieved for Accepts wildcards for searching. E.g. -Name "Application*Adaptor" Default value is "*" which will search for all files .PARAMETER Latest Instruct the cmdlet to only fetch the information of the latest file from the Azure Storage Account .EXAMPLE PS C:\> Get-D365AzureStorageFile -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Container "backupfiles" This will get information for all files in the blob container "backupfiles". It will use the AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" to gain access. .EXAMPLE PS C:\> Get-D365AzureStorageFile -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Container "backupfiles" -Latest This will get information for the latest (newest) file from the blob container "backupfiles". It will use the AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" to gain access to the container. .EXAMPLE PS C:\> Get-D365AzureStorageFile -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Container "backupfiles" -Name "*UAT*" This will get information for all files in the blob container "backupfiles" that fits the "*UAT*" search value. It will use the AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" to gain access to the container. .EXAMPLE PS C:\> Get-D365AzureStorageFile -AccountId "miscfiles" -SAS "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" -Container "backupfiles" -Latest This will get information for the latest (newest) file from the blob container "backupfiles". It will use the SAS key "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" to gain access to the container. .NOTES Tags: Azure, Azure Storage, Token, Blob, File, Container Author: Mötz Jensen (@Splaxi) Author: Florian Hopfner (@FH-Inway) #> function Get-D365AzureStorageFile { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [string] $AccountId = $Script:AzureStorageAccountId, [string] $AccessToken = $Script:AzureStorageAccessToken, [string] $SAS = $Script:AzureStorageSAS, [Alias('Blob')] [Alias('Blobname')] [string] $Container = $Script:AzureStorageContainer, [Parameter(ParameterSetName = 'Default')] [Alias('FileName')] [string] $Name = "*", [Parameter(Mandatory = $true, ParameterSetName = 'Latest')] [Alias('GetLatest')] [switch] $Latest ) $connectionInformation = ($AccountId -and $Container) $authenticationInformation = ($AccessToken -or $SAS) if (-not ($connectionInformation -and $authenticationInformation)) { 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." Stop-PSFFunction -Message "Stopping because of missing parameters" return } Invoke-TimeSignal -Start if ([string]::IsNullOrEmpty($SAS)) { Write-PSFMessage -Level Verbose -Message "Working against Azure Storage Account with AccessToken" $storageContext = New-AzStorageContext -StorageAccountName $AccountId.ToLower() -StorageAccountKey $AccessToken } else { Write-PSFMessage -Level Verbose -Message "Working against Azure Storage Account with SAS" $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) $storageContext = New-AzStorageContext -ConnectionString $conString } try { $files = Get-AzStorageBlob -Container $($Container.ToLower()) -Context $storageContext | Sort-Object -Descending { $_.LastModified } $selectParams = @{ TypeName = "D365FO.TOOLS.Azure.Blob" Property = "Name", "Length as Size to PSFSize", "LastModified" } if ($Latest) { $files | Select-Object -First 1 | Select-PSFObject @selectParams } else { $filteredFiles = $files | Where-Object { $_.Name -Like $Name } foreach ($fileInfo in $filteredFiles) { $fileInfo | Select-PSFObject @selectParams } } } catch { Write-PSFMessage -Level Warning -Message "Something broke" -ErrorRecord $_ } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/get-d365azurestorageurl.ps1 ================================================  <# .SYNOPSIS Get a blob Url from Azure Storage account .DESCRIPTION Get a valid blob container url from an Azure Storage Account .PARAMETER AccountId Storage Account Name / Storage Account Id you want to work against .PARAMETER SAS The SAS key that you have created for the storage account or blob container .PARAMETER Container Name of the blob container inside the storage account you want to work against .PARAMETER OutputAsHashtable Instruct the cmdlet to return a hastable object .EXAMPLE PS C:\> Get-D365AzureStorageUrl -AccountId "miscfiles" -SAS "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" -Container "backupfiles" This will generate a valid Url for the blob container in the Azure Storage Account. It will use the AccountId "miscfiles" as the name of the storage account. It will use the SAS key "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" to add the SAS token/key to the Url. It will use the Container "backupfiles" as the container name in the Url. .EXAMPLE PS C:\> Get-D365AzureStorageUrl This will generate a valid Url for the blob container in the Azure Storage Account. It will use the default values that are configured using the Set-D365ActiveAzureStorageConfig cmdlet and view using the Get-D365ActiveAzureStorageConfig cmdlet. .EXAMPLE PS C:\> Get-D365AzureStorageUrl -OutputAsHashtable This will generate a valid Url for the blob container in the Azure Storage Account. It will use the default values that are configured using the Set-D365ActiveAzureStorageConfig cmdlet and view using the Get-D365ActiveAzureStorageConfig cmdlet. The output object will be a Hashtable, which you can use as a parameter for other cmdlets. .EXAMPLE PS C:\> $DestinationParms = Get-D365AzureStorageUrl -OutputAsHashtable PS C:\> $BlobFileDetails = Get-D365LcsDatabaseBackups -Latest | Invoke-D365AzCopyTransfer @DestinationParms PS C:\> $BlobFileDetails | Invoke-D365AzCopyTransfer -DestinationUri "C:\Temp" -DeleteOnTransferComplete This will transfer the lastest backup file from LCS Asset Library to your local "C:\Temp". It will get a destination Url, for it to transfer the backup file between the LCS storage account and your own. The newly transfered file, that lives in your own storage account, will then be downloaded to your local "c:\Temp". After the file has been downloaded to your local "C:\Temp", it will be deleted from your own storage account. .NOTES Tags: Azure, Azure Storage, Token, Blob, File, Container, LCS, Asset, Bacpac, Backup Author: Mötz Jensen (@Splaxi) #> function Get-D365AzureStorageUrl { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')] [CmdletBinding()] param ( [string] $AccountId = $Script:AzureStorageAccountId, [string] $SAS = $Script:AzureStorageSAS, [Alias('Blob')] [Alias('Blobname')] [string] $Container = $Script:AzureStorageContainer, [switch] $OutputAsHashtable ) if (([string]::IsNullOrEmpty($AccountId) -eq $true) -or ([string]::IsNullOrEmpty($Container)) -or ([string]::IsNullOrEmpty($SAS))) { 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." Stop-PSFFunction -Message "Stopping because of missing parameters" return } Invoke-TimeSignal -Start if ($SAS.StartsWith("?")) { $SAS = $SAS.Substring(1) } $res = @{ DestinationUri = $("https://{0}.blob.core.windows.net/{1}?{2}" -f $AccountId.ToLower(), $Container, $SAS) } if ($OutputAsHashtable) { $res } else { [PSCustomObject]$res } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/get-d365bacpacsqloptions.ps1 ================================================  <# .SYNOPSIS Get the SQL Server options from the bacpac model.xml file .DESCRIPTION Extract the SQL Server options that are listed inside the model.xml file originating from a bacpac file .PARAMETER Path Path to the extracted model.xml file that you want to work against .EXAMPLE PS C:\> Get-D365BacpacSqlOptions -Path "c:\temp\d365fo.tools\bacpac.model.xml" This will display all the SQL Server options configured in the bacpac model file. .EXAMPLE PS C:\> Export-D365BacpacModelFile -Path "c:\Temp\AxDB.bacpac" | Get-D365BacpacSqlOptions This will display all the SQL Server options configured in the bacpac file. First it will export the model.xml from the "c:\Temp\AxDB.bacpac" file, using the Export-D365BacpacModelFile function. The output from Export-D365BacpacModelFile will be piped into the Get-D365BacpacSqlOptions function. .NOTES Tags: Bacpac, Servicing, Data, SqlPackage, Sql Server Options, Collation Author: Mötz Jensen (@Splaxi) #> function Get-D365BacpacSqlOptions { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [Alias("Get-D365SqlOptionsFromBacpacModelFile")] [CmdletBinding()] param ( [Parameter(ValueFromPipelineByPropertyName = $true)] [Alias('ModelFile')] [Alias('File')] [string] $Path ) begin { Invoke-TimeSignal -Start } process { if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } $reader = [System.Xml.XmlReader]::Create($Path) $break = $false while ($reader.read() -and -not ($break)) { switch ($reader.NodeType) { ([System.Xml.XmlNodeType]::Element) { if ($reader.Name -eq "Element") { if ($reader.GetAttribute("Type") -eq "SqlDatabaseOptions") { if ($reader.ReadToDescendant("Property")) { do { [PSCustomObject]@{OptionName = $reader.GetAttribute("Name") OptionValue = $reader.GetAttribute("Value") } } while ($reader.ReadToNextSibling("Property")) } $break = $true break } } break } } } } end { if ($reader) { $reader.Close() $reader.Dispose() } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/get-d365bacpactable.ps1 ================================================  <# .SYNOPSIS Get tables from the bacpac file .DESCRIPTION Get tables and their metadata from the bacpac file 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 .PARAMETER Path Path to the bacpac file that you want to work against It can also be a zip file .PARAMETER Table Name of the table that you want to delete the data for Supports an array of table names If a schema name isn't supplied as part of the table name, the cmdlet will prefix it with "dbo." Supports wildcard searching e.g. "Sales*" will locate all "dbo.Sales*" tables in the bacpac file .PARAMETER Top Instruct the cmdlet with how many tables you want returned Default is [int]::max, which translates into all tables present inside the bapcac file .PARAMETER SortSizeAsc Instruct the cmdlet to sort the output by size (original) ascending .PARAMETER SortSizeDesc Instruct the cmdlet to sort the output by size (original) descending .EXAMPLE PS C:\> Get-D365BacpacTable -Path "c:\Temp\AxDB.bacpac" This will return all tables from inside the bacpac file. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "*" as the Table parameter, to output all tables. It uses the default value "[int]::max" as the Top parameter, to output all tables. It uses the default sort, which is by name acsending. A result set example: Name OriginalSize CompressedSize BulkFiles ---- ------------ -------------- --------- ax.DBVERSION 62 B 52 B 1 crt.RETAILUPGRADEHISTORY 13,49 MB 13,41 MB 3 dbo.__AOSMESSAGEREGISTRATION 1,80 KB 540 B 2 dbo.__AOSSTARTUPVERSION 4 B 6 B 1 dbo.ACCOUNTINGDISTRIBUTION 48,60 MB 4,50 MB 95 dbo.ACCOUNTINGEVENT 11,16 MB 1,51 MB 128 dbo.AGREEMENTPARAMETERS_RU 366 B 113 B 1 dbo.AIFSQLCDCENABLEDTABLES 13,63 KB 2,19 KB 1 dbo.AIFSQLCHANGETRACKINGENABLEDTABLES 9,89 KB 1,42 KB 1 dbo.AIFSQLCTTRIGGERS 44,75 KB 6,29 KB 1 .EXAMPLE PS C:\> Get-D365BacpacTable -Path "c:\Temp\AxDB.bacpac" -SortSizeAsc This will return all tables from inside the bacpac file, sorted by the original size, ascending. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "*" as the Table parameter, to output all tables. It uses the default value "[int]::max" as the Top parameter, to output all tables. It uses the SortSizeAsc parameter, which is by original size acsending. A result set example: Name OriginalSize CompressedSize BulkFiles ---- ------------ -------------- --------- dbo.__AOSSTARTUPVERSION 4 B 6 B 1 dbo.SYSSORTORDER 20 B 20 B 1 dbo.SECURITYDATABASESETTINGS 20 B 12 B 1 dbo.SYSPOLICYSEQUENCEGROUP 24 B 10 B 1 dbo.SYSFILESTOREPARAMETERS 26 B 10 B 1 dbo.SYSHELPCPSSETUP 28 B 15 B 1 dbo.DATABASELOGPARAMETERS 28 B 10 B 1 dbo.FEATUREMANAGEMENTPARAMETERS 28 B 10 B 1 dbo.AIFSQLCTVERSION 28 B 24 B 1 dbo.SYSHELPSETUP 28 B 15 B 1 .EXAMPLE PS C:\> Get-D365BacpacTable -Path "c:\Temp\AxDB.bacpac" -SortSizeDesc This will return all tables from inside the bacpac file, sorted by the original size, descending. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "*" as the Table parameter, to output all tables. It uses the default value "[int]::max" as the Top parameter, to output all tables. It uses the SortSizeDesc parameter, which is by original size descending. A result set example: Name OriginalSize CompressedSize BulkFiles ---- ------------ -------------- --------- dbo.TSTIMESHEETLINESTAGING 35,31 GB 2,44 GB 9077 dbo.RESROLLUP 13,30 GB 367,19 MB 3450 dbo.PROJECTSTAGING 11,31 GB 508,70 MB 2929 dbo.TSTIMESHEETTABLESTAGING 5,93 GB 246,65 MB 1564 dbo.BATCHHISTORY 5,80 GB 234,99 MB 1529 dbo.HCMPOSITIONHIERARCHYSTAGING 5,16 GB 222,18 MB 1358 dbo.ERLCSFILEASSETTABLE 3,15 GB 217,68 MB 302 dbo.EVENTINBOX 2,92 GB 105,63 MB 747 dbo.HCMPOSITIONV2STAGING 2,79 GB 200,27 MB 755 dbo.HCMEMPLOYEESTAGING 2,49 GB 218,69 MB 677 .EXAMPLE PS C:\> Get-D365BacpacTable -Path "c:\Temp\AxDB.bacpac" -SortSizeDesc -Top 5 This will return all tables from inside the bacpac file, sorted by the original size, descending. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "*" as the Table parameter, to output all tables. It uses the value 5 as the Top parameter, to output only 5 tables, based on the sorting selected. It uses the SortSizeDesc parameter, which is by original size descending. A result set example: Name OriginalSize CompressedSize BulkFiles ---- ------------ -------------- --------- dbo.TSTIMESHEETLINESTAGING 35,31 GB 2,44 GB 9077 dbo.RESROLLUP 13,30 GB 367,19 MB 3450 dbo.PROJECTSTAGING 11,31 GB 508,70 MB 2929 dbo.TSTIMESHEETTABLESTAGING 5,93 GB 246,65 MB 1564 dbo.BATCHHISTORY 5,80 GB 234,99 MB 1529 .EXAMPLE PS C:\> Get-D365BacpacTable -Path "c:\Temp\AxDB.bacpac" -Table "Sales*" This will return all tables which matches the "Sales*" wildcard search from inside the bacpac file. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "Sales*" as the Table parameter, to output all tables that matches the wildcard pattern. It uses the default value "[int]::max" as the Top parameter, to output all tables. It uses the default sort, which is by name acsending. A result set example: Name OriginalSize CompressedSize BulkFiles ---- ------------ -------------- --------- dbo.SALESPARAMETERS 4,29 KB 310 B 1 dbo.SALESPARMUPDATE 273,48 KB 24,21 KB 1 dbo.SALESQUOTATIONTOLINEPARAMETERS 4,18 KB 596 B 1 dbo.SALESSUMMARYPARAMETERS 2,95 KB 425 B 1 dbo.SALESTABLE 1,20 KB 313 B 1 dbo.SALESTABLE_W 224 B 60 B 1 dbo.SALESTABLE2LINEPARAMETERS 4,46 KB 637 B 1 .EXAMPLE PS C:\> Get-D365BacpacTable -Path "c:\Temp\AxDB.bacpac" -Table "Sales*","CUSTINVOICE*" This will return all tables which matches the "Sales*" and "CUSTINVOICE*" wildcard searches from inside the bacpac file. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "Sales*" and "CUSTINVOICE*" as the Table parameter, to output all tables that matches the wildcard pattern. It uses the default value "[int]::max" as the Top parameter, to output all tables. It uses the default sort, which is by name acsending. A result set example: Name OriginalSize CompressedSize BulkFiles ---- ------------ -------------- --------- dbo.CUSTINVOICEJOUR 2,01 MB 118,87 KB 1 dbo.CUSTINVOICELINE 14,64 MB 975,30 KB 4 dbo.CUSTINVOICELINEINTERPROJ 6,58 MB 477,97 KB 2 dbo.CUSTINVOICETABLE 1,06 MB 56,56 KB 1 dbo.CUSTINVOICETRANS 32,34 MB 1,51 MB 54 dbo.SALESPARAMETERS 4,29 KB 310 B 1 dbo.SALESPARMUPDATE 273,48 KB 24,21 KB 1 dbo.SALESQUOTATIONTOLINEPARAMETERS 4,18 KB 596 B 1 dbo.SALESSUMMARYPARAMETERS 2,95 KB 425 B 1 dbo.SALESTABLE 1,20 KB 313 B 1 dbo.SALESTABLE_W 224 B 60 B 1 dbo.SALESTABLE2LINEPARAMETERS 4,46 KB 637 B 1 .EXAMPLE PS C:\> Get-D365BacpacTable -Path "c:\Temp\AxDB.bacpac" -Table "SalesTable","CustTable" This will return the tables "dbo.SalesTable" and "dbo.CustTable" from inside the bacpac file. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "SalesTable" and "CustTable" as the Table parameter, to output the tables that matches the names. It uses the default value "[int]::max" as the Top parameter, to output all tables. It uses the default sort, which is by name acsending. A result set example: Name OriginalSize CompressedSize BulkFiles ---- ------------ -------------- --------- dbo.CUSTTABLE 154,91 KB 8,26 KB 1 dbo.SALESTABLE 1,20 KB 313 B 1 .NOTES Tags: Bacpac, Servicing, Data, SqlPackage, Table, Size, Troubleshooting Author: Mötz Jensen (@Splaxi) #> function Get-D365BacpacTable { [CmdletBinding(DefaultParameterSetName = "Default")] param ( [Parameter(Mandatory = $true)] [Alias('File')] [Alias('BacpacFile')] [string] $Path, [string[]] $Table = "*", [int] $Top = [int]::MaxValue, [Parameter(ParameterSetName = "SortSizeAsc")] [switch] $SortSizeAsc, [Parameter(ParameterSetName = "SortSizeDesc")] [switch] $SortSizeDesc ) begin { if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } $file = [System.IO.File]::Open($Path, [System.IO.FileMode]::Open) $zipArch = [System.IO.Compression.ZipArchive]::new($file) } process { if (Test-PSFFunctionInterrupt) { return } $bulkFilesArray = New-Object System.Collections.Generic.List[System.Object] foreach ($item in $table) { $fullTableName = "" if ($item -eq "*") { $fullTableName = $item } elseif (-not ($item -like "*.*")) { $fullTableName = "dbo.$item" } else { $fullTableName = $item } Write-PSFMessage -Level Verbose -Message "Looking for $fullTableName." $entries = $zipArch.Entries | Where-Object Fullname -like "Data/$fullTableName/*" $bulkFilesArray.AddRange(@($($entries | Select-Object -Property *, @{Name = "Table"; Expression = { $_.FullName.Split("/")[1] } }))) } $bulkFiles = $bulkFilesArray.ToArray() | Sort-Object -Property Fullname -Unique $grouped = $bulkFiles | Group-Object -Property Table $res = $grouped | ForEach-Object { [pscustomobject]@{ Name = $_.Name OriginalSize = [PSFSize]$($_.Group.Length | Measure-Object -sum | Select-Object -ExpandProperty sum) CompressedSize = [PSFSize]$($_.Group.CompressedLength | Measure-Object -sum | Select-Object -ExpandProperty sum) BulkFiles = $_.Count PSTypeName = 'D365FO.TOOLS.Bacpac.Table' } } if ($SortSizeAsc) { $res | Sort-Object OriginalSize | Select-Object -First $Top } elseif ($SortSizeDesc) { $res | Sort-Object OriginalSize -Descending | Select-Object -First $Top } else { $res | Sort-Object Name | Select-Object -First $Top } } end { if ($zipArch) { $bulkFilesArray.Clear() $bulkFilesArray = $null $zipArch.Dispose() } if ($file) { $file.Close() $file.Dispose() } } } ================================================ FILE: d365fo.tools/functions/get-d365broadcastmessage.ps1 ================================================  <# .SYNOPSIS Get broadcast message from the D365FO environment .DESCRIPTION Get broadcast message from the D365FO environment by looking into the database table .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER ExcludeExpired Exclude all the records that has already expired .EXAMPLE PS C:\> Get-D365BroadcastMessage This will display all the broadcast message records from the SysBroadcastMessage table. .EXAMPLE PS C:\> Get-D365BroadcastMessage -ExcludeExpired This will display all active the broadcast message records from the SysBroadcastMessage table. .NOTES Tags: Broadcast, Message, SysBroadcastMessage, Servicing, Message, Users, Environment Author: Mötz Jensen (@Splaxi) #> function Get-D365BroadcastMessage { [CmdletBinding()] [OutputType()] param ( [Parameter(Mandatory = $false, Position = 1)] [string] $DatabaseServer = $Script:DatabaseServer, [Parameter(Mandatory = $false, Position = 2)] [string] $DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, Position = 3)] [string] $SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, Position = 4)] [string] $SqlPwd = $Script:DatabaseUserPassword, [switch] $ExcludeExpired ) $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection if ($ExcludeExpired) { $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\get-broadcastmessageactive.sql") -join [Environment]::NewLine } else { $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\get-broadcastmessage.sql") -join [Environment]::NewLine } try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $reader = $sqlCommand.ExecuteReader() while ($reader.Read() -eq $true) { [PSCustomObject]@{ StartTime = [System.TimeZoneInfo]::ConvertTimeFromUtc($($reader.GetDateTime($($reader.GetOrdinal("FROMDATETIME")))), [System.TimeZoneInfo]::Local) EndTime = [System.TimeZoneInfo]::ConvertTimeFromUtc($($reader.GetDateTime($($reader.GetOrdinal("TODATETIME")))), [System.TimeZoneInfo]::Local) StartTimeUtc = [System.TimeZoneInfo]::ConvertTimeFromUtc($($reader.GetDateTime($($reader.GetOrdinal("TODATETIME")))), [System.TimeZoneInfo]::Utc) EndTimeUtc = [System.TimeZoneInfo]::ConvertTimeFromUtc($($reader.GetDateTime($($reader.GetOrdinal("TODATETIME")))), [System.TimeZoneInfo]::Utc) AOSId = "$($reader.GetString($($reader.GetOrdinal("AOSID"))))" } } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { $reader.close() if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } } ================================================ FILE: d365fo.tools/functions/get-d365broadcastmessageconfig.ps1 ================================================  <# .SYNOPSIS Get broadcast message configs .DESCRIPTION Get all broadcast message configuration objects from the configuration store .PARAMETER Name The name of the broadcast message configuration you are looking for Default value is "*" to display all broadcast message configs .PARAMETER OutputAsHashtable Instruct the cmdlet to return a hastable object .EXAMPLE PS C:\> Get-D365BroadcastMessageConfig This will display all broadcast message configurations on the machine. .EXAMPLE PS C:\> Get-D365BroadcastMessageConfig -OutputAsHashtable This will display all broadcast message configurations on the machine. Every object will be output as a hashtable, for you to utilize as parameters for other cmdlets. .EXAMPLE PS C:\> Get-D365BroadcastMessageConfig -Name "UAT" This will display the broadcast message configuration that is saved with the name "UAT" on the machine. .NOTES Tags: Servicing, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret Author: Mötz Jensen (@Splaxi) .LINK Add-D365BroadcastMessageConfig .LINK Clear-D365ActiveBroadcastMessageConfig .LINK Get-D365ActiveBroadcastMessageConfig .LINK Remove-D365BroadcastMessageConfig .LINK Send-D365BroadcastMessage .LINK Set-D365ActiveBroadcastMessageConfig #> function Get-D365BroadcastMessageConfig { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')] [CmdletBinding()] [OutputType('PSCustomObject')] param ( [string] $Name = "*", [switch] $OutputAsHashtable ) Write-PSFMessage -Level Verbose -Message "Fetch all configurations based on $Name" -Target $Name $Name = $Name.ToLower() $configurations = Get-PSFConfig -FullName "d365fo.tools.broadcast.$Name.name" foreach ($configName in $configurations.Value.ToLower()) { Write-PSFMessage -Level Verbose -Message "Working against the $configName configuration" -Target $configName $res = @{} $configName = $configName.ToLower() foreach ($config in Get-PSFConfig -FullName "d365fo.tools.broadcast.$configName.*") { $propertyName = $config.FullName.ToString().Replace("d365fo.tools.broadcast.$configName.", "") $res.$propertyName = $config.Value } if($OutputAsHashtable) { $res } else { [PSCustomObject]$res } } } ================================================ FILE: d365fo.tools/functions/get-d365clickoncetrustprompt.ps1 ================================================  <# .SYNOPSIS Get the ClickOnce configuration .DESCRIPTION Creates the needed registry keys and values for ClickOnce to work on the machine .EXAMPLE PS C:\> Get-D365ClickOnceTrustPrompt This will get the current ClickOnce configuration .NOTES Tags: ClickOnce, Registry, TrustPrompt Author: Mötz Jensen (@Splaxi) #> function Get-D365ClickOnceTrustPrompt { [CmdletBinding()] param ( ) begin { } process { Write-PSFMessage -Level Verbose -Message "Testing if the registry key exists or not" if ((Test-Path -Path "HKLM:\SOFTWARE\MICROSOFT\.NETFramework\Security\TrustManager\PromptingLevel") -eq $false) { Write-PSFMessage -Level Host -Message "It looks like ClickOnce trust prompt has never been configured on this machine. Run Set-D365ClickOnceTrustPrompt to fix that" } else { Write-PSFMessage -Level Verbose -Message "Gathering the details from registry" [PSCustomObject]@{ UntrustedSites = (Get-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\.NETFramework\Security\TrustManager\PromptingLevel" "UntrustedSites").UntrustedSites Internet = (Get-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\.NETFramework\Security\TrustManager\PromptingLevel" "Internet").Internet MyComputer = (Get-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\.NETFramework\Security\TrustManager\PromptingLevel" "MyComputer").MyComputer LocalIntranet = (Get-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\.NETFramework\Security\TrustManager\PromptingLevel" "LocalIntranet").LocalIntranet TrustedSites = (Get-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\.NETFramework\Security\TrustManager\PromptingLevel" "TrustedSites").TrustedSites } } } end { } } ================================================ FILE: d365fo.tools/functions/get-d365compilerresult.ps1 ================================================  <# .SYNOPSIS Get the compiler outputs presented .DESCRIPTION Get the compiler outputs presented in a structured manner on the screen It could be a Visual Studio compiler log or it could be a Invoke-D365ModuleCompile log you want analyzed .PARAMETER Path Path to the compiler log file that you want to work against A BuildModelResult.log or a Dynamics.AX.*.xppc.log file will both work .PARAMETER ErrorsOnly Instructs the cmdlet to only output compile results where there was errors detected .PARAMETER OutputTotals Instructs the cmdlet to output the total errors and warnings after the analysis .PARAMETER OutputAsObjects Instructs the cmdlet to output the objects instead of formatting them 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 .EXAMPLE PS C:\> Get-D365CompilerResult -Path "c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log" This will analyze the compiler log file for warning and errors. A result set example: File Warnings Errors ---- -------- ------ c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log 2 1 .EXAMPLE PS C:\> Get-D365CompilerResult -Path "c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log" -ErrorsOnly This will analyze the compiler log file for warning and errors, but only output if it has errors. A result set example: File Warnings Errors ---- -------- ------ c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log 2 1 .EXAMPLE PS C:\> Get-D365CompilerResult -Path "c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log" -ErrorsOnly -OutputAsObjects This will analyze the compiler log file for warning and errors, but only output if it has errors. The output will be PSObjects, which can be assigned to a variable and used for futher analysis. A result set example: File Warnings Errors ---- -------- ------ c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log 2 1 .EXAMPLE PS C:\> Get-D365Module -Name *Custom* | Invoke-D365ModuleCompile | Get-D365CompilerResult -OutputTotals This will find all modules with Custom in their name. It will pass thoses modules into the Invoke-D365ModuleCompile, which will compile them. It will pass the paths to each compile output log to Get-D365CompilerResult, which will analyze them for warning and errors. It will output the total number of warning and errors found. File Warnings Errors ---- -------- ------ c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log 2 1 Total Errors: 1 Total Warnings: 2 .NOTES Tags: Compiler, Build, Errors, Warnings, Tasks Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Vilmos Kintera" (twitter: @DAXRunBase) All credits goes to him for showing how to extract these information His blog can be found here: https://www.daxrunbase.com/blog/ The specific blog post that we based this cmdlet on can be found here: https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/ The github repository containing the original scrips can be found here: https://github.com/DAXRunBase/PowerShell-and-Azure #> function Get-D365CompilerResult { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')] [OutputType('[PsCustomObject]')] param ( [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('LogFile')] [string] $Path, [switch] $ErrorsOnly, [switch] $OutputTotals, [switch] $OutputAsObjects ) begin { Invoke-TimeSignal -Start $outputCollection = New-Object System.Collections.Generic.List[System.Object] } process { if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } $res = Get-CompilerResult -Path $Path if ($null -ne $res) { $outputCollection.Add($res) } } end { $totalErrors = 0 $totalWarnings = 0 $resCol = @($outputCollection.ToArray()) $totalWarnings = ($resCol | Measure-Object -Property Warnings -Sum).Sum $totalErrors = ($resCol | Measure-Object -Property Errors -Sum).Sum if($ErrorsOnly) { $resCol = @($resCol | Where-Object Errors -gt 0) } if($OutputAsObjects){ $resCol } else { $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' } } if ($OutputTotals) { Write-PSFHostColor -String "Total Errors: $totalErrors" Write-PSFHostColor -String "Total Warnings: $totalWarnings" } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/get-d365database.ps1 ================================================  <# .SYNOPSIS Get databases from the server .DESCRIPTION Get the names of databases on either SQL Server or in Azure SQL Database instance .PARAMETER Name Name of the database that you are looking for Default value is "*" which will show all databases .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .EXAMPLE PS C:\> Get-D365Database This will show all databases on the default SQL Server / Azure SQL Database instance. .EXAMPLE PS C:\> Get-D365Database -Name AXDB_ORIGINAL This will show if the AXDB_ORIGINAL database exists on the default SQL Server / Azure SQL Database instance. .NOTES Tags: Database, DB, Servicing Author: Mötz Jensen (@Splaxi) #> function Get-D365Database { [CmdletBinding()] [OutputType('[PsCustomObject]')] param ( [string[]] $Name = "*", [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword ) $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = "master"; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $sqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\get-database.sql") -join [Environment]::NewLine try { $sqlCommand.Connection.Open() $reader = $sqlCommand.ExecuteReader() while ($reader.Read() -eq $true) { $res = [PSCustomObject]@{ Name = "$($reader.GetString($($reader.GetOrdinal("NAME"))))" } if ($res.Name -NotLike $Name) { continue } $res } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { $reader.close() if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } } ================================================ FILE: d365fo.tools/functions/get-d365databaseaccess.ps1 ================================================  <# .SYNOPSIS Shows the Database Access information for the D365 Environment .DESCRIPTION Gets all database information from the D365 environment .EXAMPLE PS C:\> Get-D365DatabaseAccess This will get all relevant details, including connection details, for the database configured for the environment .NOTES Tags: Database, Connection, Sql, SqlUser, SqlPwd Author: Rasmus Andersen (@ITRasmus) The cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations. The call to the dll file gets all relevant connections details for the database server. #> function Get-D365DatabaseAccess { [CmdletBinding()] param () $environment = Get-ApplicationEnvironment return $environment.DataAccess } ================================================ FILE: d365fo.tools/functions/get-d365decryptedwebconfig.ps1 ================================================  <# .SYNOPSIS Decrypts the AOS config file .DESCRIPTION Function used for decrypting the config file used by the D365 Finance & Operations AOS service .PARAMETER OutputPath Place where the decrypted files should be placed Default value is: "c:\temp\d365fo.tools\WebConfigDecrypted" .PARAMETER AosServiceWebRootPath Location of the D365 webroot folder .EXAMPLE PS C:\> Get-D365DecryptedWebConfig This will get the config file from the instance, decrypt it and save it. IT will save the decrypted web.config file in the default location: "c:\temp\d365fo.tools\WebConfigDecrypted". A result set example: Filename LastModified File -------- ------------ ---- web.config 7/1/2021 9:01:31 PM C:\temp\d365fo.tools\WebConfigDecrypted\web.config .EXAMPLE PS C:\> Get-D365DecryptedWebConfig -OutputPath "c:\temp\d365fo.tools" This will get the config file from the instance, decrypt it and save it to "c:\temp\d365fo.tools" A result set example: Filename LastModified File -------- ------------ ---- web.config 7/1/2021 9:07:36 PM C:\temp\d365fo.tools\web.config .NOTES Tags: Configuration, Service Account, Sql, SqlUser, SqlPwd, WebConfig, Web.Config, Decryption Author : Rasmus Andersen (@ITRasmus) Author : Mötz Jensen (@splaxi) Used for getting the Password for the database and other service accounts used in environment #> function Get-D365DecryptedWebConfig { [Alias("Get-D365DecryptedConfigFile")] param( [string] $OutputPath = "c:\temp\d365fo.tools\WebConfigDecrypted", [string] $AosServiceWebRootPath = $Script:AOSPath ) $WebConfigFile = Join-Path $AosServiceWebRootPath $Script:WebConfig if (!(Test-PathExists -Path $WebConfigFile -Type Leaf)) { return } if (!(Test-PathExists -Path $OutputPath -Type Container -Create)) { return } Write-PSFMessage -Level Verbose -Message "Starting the decryption logic" New-DecryptedFile $WebConfigFile $OutputPath $file = Get-Item -Path "$OutputPath\web.config" -ErrorAction SilentlyContinue if ($null -eq $file) { $messageString = "There was an error while decrypting the web.config file." Write-PSFMessage -Level Host -Message $messageString Stop-PSFFunction -Message "Stopping because the web.config file wasn't decrypted." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) return } $file | Select-PSFObject "Name as Filename", "LastWriteTime as LastModified", "Fullname as File" } ================================================ FILE: d365fo.tools/functions/get-d365defaultmodelfornewprojects.ps1 ================================================  <# .SYNOPSIS Get the default model used creating new projects in Visual Studio .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 .EXAMPLE PS C:\> Get-D365DefaultModelForNewProjects This will display the current default module registered in the "DynamicsDevConfig.xml" file. Located in Documents\Visual Studio Dynamics 365\ or in Documents\Visual Studio 2015\Settings\ depending on the version. .NOTES Tag: Model, Models, Development, Default Model, Module, Project Author: Mötz Jensen (@Splaxi) The work for this cmdlet / function was inspired by Robin Kretzschmar (@DarkSmile92) blog post about changing the default model. The direct link for his blog post is: https://robscode.onl/d365-set-default-model-for-new-projects/ His main blog can found here: https://robscode.onl/ #> function Get-D365DefaultModelForNewProjects { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param () $filePath = "$env:UserProfile\Documents\Visual Studio Dynamics 365\DynamicsDevConfig.xml" if (-not (Test-PathExists -Path $filePath -Type Leaf)) { $filePath = "$env:UserProfile\Documents\Visual Studio 2015\Settings\DynamicsDevConfig.xml" } if (-not (Test-PathExists -Path $filePath -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } $namespace = @{ns = "http://schemas.microsoft.com/dynamics/2012/03/development/configuration" } $defaultModel = Select-Xml -XPath "/ns:DynamicsDevConfig/ns:DefaultModelForNewProjects" -Path $filePath -Namespace $namespace $modelName = $defaultModel.Node.InnerText [PSCustomObject] @{DefaultModelForNewProjects = $modelName } } ================================================ FILE: d365fo.tools/functions/get-d365dotnetclass.ps1 ================================================  <# .SYNOPSIS Get a .NET class from the Dynamics 365 for Finance and Operations installation .DESCRIPTION Get a .NET class from an assembly file (dll) from the package directory .PARAMETER Name Name of the .NET class that you are looking for Accepts wildcards for searching. E.g. -Name "ER*Excel*" Default value is "*" which will search for all classes .PARAMETER Assembly Name of the assembly file that you want to search for the .NET class Accepts wildcards for searching. E.g. -Name "*AX*Framework*.dll" Default value is "*.dll" which will search for assembly files .PARAMETER PackageDirectory Path to the directory containing the installed packages Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Get-D365DotNetClass -Name "ERText*" Will search across all assembly files (*.dll) that are located in the default package directory after any class that fits the search "ERText*" .EXAMPLE PS C:\> Get-D365DotNetClass -Name "ERText*" -Assembly "*LocalizationFrameworkForAx.dll*" Will search across all assembly files (*.dll) that are fits the search "*LocalizationFrameworkForAx.dll*", that are located in the default package directory, after any class that fits the search "ERText*" .EXAMPLE PS C:\> Get-D365DotNetClass -Name "ERText*" | Export-Csv -Path c:\temp\results.txt -Delimiter ";" Will search across all assembly files (*.dll) that are located in the default package directory after any class that fits the search "ERText*" The output is saved to a file to make it easier to search inside the result set .NOTES Tags: .Net, DotNet, Class, Development Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. #> function Get-D365DotNetClass { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )] [string] $Name = "*", [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )] [string] $Assembly = "*.dll", [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 3 )] [string] $PackageDirectory = $Script:PackageDirectory ) begin { } process { Invoke-TimeSignal -Start $files = (Get-ChildItem -Path $PackageDirectory -Filter $Assembly -Recurse -Exclude "*Resources*" | Where-Object Fullname -Notlike "*Resources*" ) $files | ForEach-Object { $path = $_.Fullname try { Write-PSFMessage -Level Verbose -Message "Loading the dll file: $path" -Target $path [Reflection.Assembly]$ass = [Reflection.Assembly]::LoadFile($path) $res = $ass.GetTypes() Write-PSFMessage -Level Verbose -Message "Looping through all types from the assembly" foreach ($obj in $res) { if ($obj.Name -NotLike $Name) { continue } [PSCustomObject]@{ IsPublic = $obj.IsPublic IsSerial = $obj.IsSerial Name = $obj.Name BaseType = $obj.BaseType File = $path } } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while trying to load the path: $path" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } Invoke-TimeSignal -End } end { } } ================================================ FILE: d365fo.tools/functions/get-d365dotnetmethod.ps1 ================================================  <# .SYNOPSIS Get a .NET method from the Dynamics 365 for Finance and Operations installation .DESCRIPTION Get a .NET method from an assembly file (dll) from the package directory .PARAMETER Assembly Name of the assembly file that you want to search for the .NET method Provide the full path for the assembly file you want to work against .PARAMETER Name Name of the .NET method that you are looking for Accepts wildcards for searching. E.g. -Name "parmER*Excel*" Default value is "*" which will search for all methods .PARAMETER TypeName Name of the .NET class that you want to work against Accepts wildcards for searching. E.g. -Name "*ER*Excel*" Default value is "*" which will work against all classes .EXAMPLE PS C:\> Get-D365DotNetMethod -Assembly "C:\AOSService\PackagesLocalDirectory\ElectronicReporting\bin\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll" Will get all methods, across all classes, from the assembly file .EXAMPLE PS C:\> Get-D365DotNetMethod -Assembly "C:\AOSService\PackagesLocalDirectory\ElectronicReporting\bin\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll" -TypeName "ERTextFormatExcelFileComponent" Will get all methods, from the "ERTextFormatExcelFileComponent" class, from the assembly file .EXAMPLE PS C:\> Get-D365DotNetMethod -Assembly "C:\AOSService\PackagesLocalDirectory\ElectronicReporting\bin\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll" -TypeName "ERTextFormatExcelFileComponent" -Name "*parm*" Will get all methods that fits the search "*parm*", from the "ERTextFormatExcelFileComponent" class, from the assembly file .EXAMPLE PS C:\> Get-D365DotNetClass -Name "ERTextFormatExcelFileComponent" -Assembly "*LocalizationFrameworkForAx.dll*" | Get-D365DotNetMethod Will get all methods, from the "ERTextFormatExcelFileComponent" class, from any assembly file that fits the search "*LocalizationFrameworkForAx.dll*" .NOTES Tags: .Net, DotNet, Class, Method, Methods, Development Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. #> function Get-D365DotNetMethod { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 1 )] [Alias('File')] [string] $Assembly, [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )] [Alias('MethodName')] [string] $Name = "*", [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 3 )] [Alias('ClassName')] [string] $TypeName = "*" ) begin { } process { Invoke-TimeSignal -Start try { Write-PSFMessage -Level Verbose -Message "Loading the file" -Target $Assembly [Reflection.Assembly]$ass = [Reflection.Assembly]::LoadFile($Assembly) $types = $ass.GetTypes() foreach ($obj in $types) { Write-PSFMessage -Level Verbose -Message "Type name loaded" -Target $obj.Name if ($obj.Name -NotLike $TypeName) {continue} $members = $obj.GetMethods() foreach ($objI in $members) { if ($objI.Name -NotLike $Name) { continue } [PSCustomObject]@{ TypeName = $obj.Name TypeIsPublic = $obj.IsPublic MethodName = $objI.Name } } } } catch { Write-PSFMessage -Level Warning -Message "Something went wrong while working on: $Assembly" -ErrorRecord $_ } Invoke-TimeSignal -End } end { } } ================================================ FILE: d365fo.tools/functions/get-d365environment.ps1 ================================================  <# .SYNOPSIS Cmdlet to get the current status for the different services in a Dynamics 365 Finance & Operations environment .DESCRIPTION List status for all relevant services that is running in a D365FO environment .PARAMETER ComputerName An array of computers that you want to query for the services status on. .PARAMETER All Set when you want to query all relevant services Includes: Aos Batch Financial Reporter DMF .PARAMETER Aos Instruct the cmdlet to query the AOS (IIS) service .PARAMETER Batch Instruct the cmdlet query the batch service .PARAMETER FinancialReporter Instruct the cmdlet query the financial reporter (Management Reporter 2012) .PARAMETER DMF Instruct the cmdlet query the DMF service .PARAMETER OnlyStartTypeAutomatic Instruct the cmdlet to filter out services that are set to manual start or disabled .PARAMETER OutputServiceDetailsOnly Instruct the cmdlet to exclude the server name from the output .EXAMPLE PS C:\> Get-D365Environment Will query all D365FO service on the machine. .EXAMPLE PS C:\> Get-D365Environment -All Will query all D365FO service on the machine. .EXAMPLE PS C:\> Get-D365Environment -OnlyStartTypeAutomatic Will query all D365FO service on the machine. It will filter out all services that are either configured as manual or disabled. .EXAMPLE PS C:\> Get-D365Environment -ComputerName "TEST-SB-AOS1","TEST-SB-AOS2","TEST-SB-BI1" -All Will query all D365FO service on the different machines. .EXAMPLE PS C:\> Get-D365Environment -Aos -Batch Will query the Aos & Batch services on the machine. .EXAMPLE PS C:\> Get-D365Environment -FinancialReporter -DMF Will query the FinancialReporter & DMF services on the machine. .EXAMPLE PS C:\> Get-D365Environment -OutputServiceDetailsOnly Will query all D365FO service on the machine. Will omit the servername from the output. .EXAMPLE PS C:\> Get-D365Environment -FinancialReporter | Set-Service -StartupType Manual This will configure the Financial Reporter services to be start type manual. .NOTES Tags: Environment, Service, Services, Aos, Batch, Servicing Author: Mötz Jensen (@Splaxi) #> function Get-D365Environment { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueSwitchParameter", "")] [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )] [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 1 )] [string[]] $ComputerName = @($env:computername), [Parameter(Mandatory = $false, ParameterSetName = 'Default')] [switch] $All = $true, [Parameter(Mandatory = $false, ParameterSetName = 'Specific')] [switch] $Aos, [Parameter(Mandatory = $false, ParameterSetName = 'Specific')] [switch] $Batch, [Parameter(Mandatory = $false, ParameterSetName = 'Specific')] [switch] $FinancialReporter, [Parameter(Mandatory = $false, ParameterSetName = 'Specific')] [switch] $DMF, [switch] $OnlyStartTypeAutomatic, [switch] $OutputServiceDetailsOnly ) if ($PSCmdlet.ParameterSetName -eq "Specific") { $All = $false } if ( (-not ($All)) -and (-not ($Aos)) -and (-not ($Batch)) -and (-not ($FinancialReporter)) -and (-not ($DMF))) { Write-PSFMessage -Level Host -Message "You have to use at least one switch when running this cmdlet. Please run the cmdlet again." Stop-PSFFunction -Message "Stopping because of missing parameters" return } $Params = Get-DeepClone $PSBoundParameters if($Params.ContainsKey("ComputerName")){$null = $Params.Remove("ComputerName")} if($Params.ContainsKey("OutputServiceDetailsOnly")){$null = $Params.Remove("OutputServiceDetailsOnly")} if($Params.ContainsKey("OnlyStartTypeAutomatic")){$null = $Params.Remove("OnlyStartTypeAutomatic")} $Services = Get-ServiceList @Params $Results = foreach ($server in $ComputerName) { Get-Service -ComputerName $server -Name $Services -ErrorAction SilentlyContinue | Select-Object @{Name = "Server"; Expression = {$Server}}, Name, Status, StartType, DisplayName } $outputTypeName = "D365FO.TOOLS.Environment.Service" if($OutputServiceDetailsOnly) { $outputTypeName = "D365FO.TOOLS.Environment.Service.Minimal" } if($OnlyStartTypeAutomatic){ $Results = $Results | Where-Object StartType -eq "Automatic" } $Results | Select-PSFObject -TypeName $outputTypeName Server, DisplayName, Status, StartType, Name } ================================================ FILE: d365fo.tools/functions/get-d365environmentsettings.ps1 ================================================  <# .SYNOPSIS Get the D365FO environment settings .DESCRIPTION Gets all settings the Dynamics 365 for Finance & Operations environment uses. .EXAMPLE PS C:\> Get-D365EnvironmentSettings This will get all details available for the environment .EXAMPLE PS C:\> Get-D365EnvironmentSettings | Format-Custom -Property * This will get all details available for the environment and format it to show all details in a long custom object. .NOTES Tags: Environment, Configuration, WebConfig, Web.Config, Decryption Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) The cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations. The call to the dll file gets all relevant details for the installation. #> function Get-D365EnvironmentSettings { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param () Get-ApplicationEnvironment } ================================================ FILE: d365fo.tools/functions/get-d365eventtraceprovider.ps1 ================================================  <# .SYNOPSIS Get D365FO Event Trace Provider .DESCRIPTION Get the full list of available Event Trace Providers for Dynamics 365 for Finance and Operations .PARAMETER Name Name of the provider that you are looking for Default value is "*" to show all Event Trace Providers Accepts an array of names, and will automatically add wildcard searching characters for each entry .EXAMPLE PS C:\> Get-D365EventTraceProvider Will list all available Event Trace Providers on a D365FO server. It will use the default option for the "Name" parameter. .EXAMPLE PS C:\> Get-D365EventTraceProvider -Name Tax Will list all available Event Trace Providers on a D365FO server which contains the keyvword "Tax". It will use the Name parameter value "Tax" while searching for Event Trace Providers. .EXAMPLE PS C:\> Get-D365EventTraceProvider -Name Tax,MR Will list all available Event Trace Providers on a D365FO server which contains the keyvword "Tax" or "MR". It will use the Name parameter array value ("Tax","MR") while searching for Event Trace Providers. .NOTES Tags: ETL, EventTracing, EventTrace Author: Mötz Jensen (@Splaxi) This cmdlet/function was inspired by the work of Michael Stashwick (@D365Stuff) He blog is located here: https://www.d365stuff.co/ 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/ #> function Get-D365EventTraceProvider { [CmdletBinding()] param ( [string[]] $Name = @("*") ) begin{ $providers = Get-NetEventProvider -ShowInstalled | Where-Object name -like "Microsoft-Dynamics*" | Sort-Object name } process { foreach ($searchName in $Name) { $providers | Where-Object name -Like "*$searchName*" | Select-PSFObject "Name as ProviderName" } } } ================================================ FILE: d365fo.tools/functions/get-d365externalip.ps1 ================================================  <# .SYNOPSIS Get the external IP address .DESCRIPTION Get the external IP address by calling an external webpage and interpret the result from that .PARAMETER SaveToClipboard Instruct the cmdlet to copy the IP address directly into the clipboard, to save you the trouble .EXAMPLE PS C:\> Get-D365ExternalIP Will call the external page, interpret the output and display it as output. A result set example: IpAddress --------- 40.113.130.229 .EXAMPLE PS C:\> Get-D365ExternalIP -SaveToClipboard Will call the external page, interpret the output and display it as output. It will save/copy the IP address into the clipboard. A result set example: IpAddress --------- 40.113.130.229 .NOTES Tags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB, IP Author: Mötz Jensen (@Splaxi) #> function Get-D365ExternalIP { [CmdletBinding()] param ( [switch] $SaveToClipboard ) begin { } process { $res = [PSCustomObject]@{"IpAddress" = (Invoke-WebRequest -Uri "https://ifconfig.me/ip").Content } if ($SaveToClipboard) { $res.IpAddress | Set-Clipboard } $res } end { } } ================================================ FILE: d365fo.tools/functions/get-d365flight.ps1 ================================================  <# .SYNOPSIS Used to get a flight .DESCRIPTION Provides a method for listing a flight in D365FO. .PARAMETER FlightName Name of the flight that you are looking for Supports wildcards "*" .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .EXAMPLE PS C:\> Get-D365Flight This will list all flights that are configured on the environment. It will show the name and the enabled status. A result set example: FlightName Enabled FlightServiceId ---------- ------- --------------- WHSWorkCancelForcedFlight 1 12719367 TAMRebateGlobalEnableFeature 1 12719367 EnablePerfInfoSimpleLoggerV2 1 12719367 EnablePerfInfoLogODataV2 1 12719367 EnablePerfInfoLogEtwRequestTableV2 1 12719367 EnablePerfInfoCursorLayerV2 1 12719367 EnablePerfInfoFormEngineLayerV2 1 12719367 EnablePerfInfoMutexWaitLayerV2 1 12719367 EnablePerfInfoSecurityLayerV2 1 12719367 EnablePerfInfoSessionLayerV2 1 12719367 EnablePerfInfoSQLLayerV2 1 12719367 EnablePerfInfoXppContainerLayerV2 1 12719367 .EXAMPLE PS C:\> Get-D365Flight -FlightName WHSWorkCancelForcedFlight This will list the flight with the specified name on the environment. It will show the name and the enabled status. A result set example: FlightName Enabled FlightServiceId ---------- ------- --------------- WHSWorkCancelForcedFlight 1 12719367 .EXAMPLE PS C:\> Get-D365Flight -FlightName WHS* This will list the flight with the specified pattern on the environment. It will filter the output to match the "WHS*" pattern. It will show the name and the enabled status. A result set example: FlightName Enabled FlightServiceId ---------- ------- --------------- WHSWorkCancelForcedFlight 1 12719367 .NOTES Tags: Flight, Flighting Author: Mötz Jensen (@Splaxi) At no circumstances can this cmdlet be used to enable a flight in a PROD environment. #> function Get-D365Flight { [CmdletBinding()] param ( [String] $FlightName = "*", [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword ) try { $WebConfigFile = join-Path -path $Script:AOSPath $Script:WebConfig Write-PSFMessage -Level Verbose -Message "Retrieve the FlightingServiceCatalogID" -Target $WebConfigFile $FlightServiceNode = Select-Xml -XPath "/configuration/appSettings/add[@key='DataAccess.FlightingServiceCatalogID']/@value" -Path $WebConfigFile $FlightServiceId = $FlightServiceNode.Node.Value Write-PSFMessage -Level Verbose -Message "FlightingServiceCatalogID: $FlightServiceId" -Target $WebConfigFile } catch { Write-PSFMessage -Level Host -Message "Something went wrong while reading from the web.config file" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } if ($null -eq $FlightServiceId) { 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" Stop-PSFFunction -Message "Stopping because of errors" return } $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\get-flight.sql") -join [Environment]::NewLine try { $sqlCommand.Connection.Open() $reader = $sqlCommand.ExecuteReader() while ($reader.Read() -eq $true) { $res = [PSCustomObject]@{ FlightName = "$($reader.GetString($($reader.GetOrdinal("FLIGHTNAME"))))" Enabled = [System.Convert]::ToBoolean($($reader.GetInt32($($reader.GetOrdinal("ENABLED"))))) FlightServiceId = "$($reader.GetInt32($($reader.GetOrdinal("FLIGHTSERVICEID"))))" } if ($res.FlightName -NotLike $FlightName) { continue } if ($res.FlightServiceId -NotLike $FlightServiceId) { continue } $res } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { $reader.close() if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } } ================================================ FILE: d365fo.tools/functions/get-d365iispreload.ps1 ================================================  <# .SYNOPSIS Gets IIS Preload status for the AOSService application pool and website. .DESCRIPTION Returns the current IIS Preload configuration for the AOSService application: - Application Pool Start Mode - Idle Time-out - Website Preload Enabled - doAppInitAfterRestart (if Application Initialization is installed) .OUTPUTS System.Management.Automation.PSCustomObject A custom object containing the following properties: - AppPool: Name of the application pool (AOSService) - StartMode: Start mode of the application pool (e.g., AlwaysRunning) - IdleTimeout: Idle timeout of the application pool (e.g., 00:00:00) - Site: Name of the website (AOSService) - PreloadEnabled: Indicates if preload is enabled for the website (True/False) - DoAppInitAfterRestart: Indicates if doAppInitAfterRestart is enabled (if Application Initialization is installed) - PreloadPage: The initialization page configured for preload (if any) - IISApplicationInitFeature: State of the IIS Application Initialization feature (Installed/Not installed) .EXAMPLE PS C:\> Get-D365IISPreload Retrieves the IIS Preload configuration for the AOSService application pool and website. .NOTES Author: Florian Hopfner (FH-Inway) 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) Written with GitHub Copilot GPT-4.1, mostly in agent mode. See commits for prompts. .LINK Enable-D365IISPreload .LINK Disable-D365IISPreload #> function Get-D365IISPreload { [CmdletBinding()] param () if (-not (Get-Module -ListAvailable -Name WebAdministration)) { 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" return } Import-Module WebAdministration -ErrorAction Stop $iisAppInitFeature = Get-WindowsFeature -Name Web-AppInit -ErrorAction SilentlyContinue $iisAppInitState = if ($iisAppInitFeature -and $iisAppInitFeature.Installed) { 'Installed' } else { 'Not installed' } $appPool = "AOSService" $site = "AOSService" $startModeProperty = Get-ItemProperty "IIS:\AppPools\$appPool" -Name startMode $startMode = $startModeProperty.Trim() # Ensure we get the value as a string without additional NoteProperty $idleTimeoutValue = (Get-ItemProperty "IIS:\AppPools\$appPool" -Name processModel.idleTimeout).Value $idleTimeout = if ($idleTimeoutValue -eq [TimeSpan]::Zero) { "0" } else { $idleTimeoutValue.ToString() } $preloadEnabled = (Get-ItemProperty "IIS:\Sites\$site" -Name applicationDefaults.preloadEnabled).Value $getDoAppInitParams = @{ pspath = 'MACHINE/WEBROOT/APPHOST' filter = 'system.webServer/applicationInitialization' name = 'doAppInitAfterRestart' location = $site ErrorAction = 'Stop' } $doAppInitAfterRestart = $null try { $doAppInitAfterRestart = (Get-WebConfigurationProperty @getDoAppInitParams).Value } catch { $doAppInitAfterRestart = "Not available" } $getInitPagesParams = @{ pspath = 'MACHINE/WEBROOT/APPHOST' filter = 'system.webServer/applicationInitialization' name = '.' location = $site ErrorAction = 'Stop' } $preloadPage = $null try { $initPages = Get-WebConfigurationProperty @getInitPagesParams if ($initPages -and $initPages.Collection -and $initPages.Collection.Count -gt 0) { $preloadPage = $initPages.Collection[0].initializationPage } else { $preloadPage = "Not configured" } } catch { $preloadPage = "Not available" } [PSCustomObject]@{ AppPool = $appPool StartMode = $startMode IdleTimeout = $idleTimeout Site = $site PreloadEnabled = $preloadEnabled DoAppInitAfterRestart = $doAppInitAfterRestart PreloadPage = $preloadPage IISApplicationInitFeature = $iisAppInitState } } ================================================ FILE: d365fo.tools/functions/get-d365installedhotfix.ps1 ================================================  <# .SYNOPSIS Get installed hotfix (DEPRECATED) .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. .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the AOS Service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the PackagesLocalDirectory Default path is the same as the AOS Service PackagesLocalDirectory .PARAMETER Model Name of the model that you want to work against Accepts wildcards for searching. E.g. -Model "*Retail*" Default value is "*" which will search for all models .PARAMETER Name Name of the hotfix that you are looking for Accepts wildcards for searching. E.g. -Name "7045*" Default value is "*" which will search for all hotfixes .PARAMETER KB KB number of the hotfix that you are looking for Accepts wildcards for searching. E.g. -KB "4045*" Default value is "*" which will search for all KB's .EXAMPLE PS C:\> Get-D365InstalledHotfix This will display all installed hotfixes found on this machine .EXAMPLE PS C:\> Get-D365InstalledHotfix -Model "*retail*" This will display all installed hotfixes found for all models that matches the search for "*retail*" found on this machine .EXAMPLE PS C:\> Get-D365InstalledHotfix -Model "*retail*" -KB "*43*" 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 .NOTES Tags: Hotfix, Servicing, Model, Models, KB, Patch, Patching, PackagesLocalDirectory Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Ievgen Miroshnikov" (twitter: @IevgenMir) All credits goes to him for showing how to extract these information His blog can be found here: https://ievgensaxblog.wordpress.com The specific blog post that we based this cmdlet on can be found here: https://ievgensaxblog.wordpress.com/2017/11/17/d365foe-get-list-of-installed-metadata-hotfixes-using-metadata-api/ #> function Get-D365InstalledHotfix { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )] [string] $BinDir = "$Script:BinDir\bin", [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )] [string] $PackageDirectory = $Script:PackageDirectory, [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 3 )] [string] $Model = "*", [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 4 )] [string] $Name = "*", [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 5 )] [string] $KB = "*" ) begin { } process { $files = @((Join-Path -Path $BinDir -ChildPath "Microsoft.Dynamics.AX.Metadata.Storage.dll"), (Join-Path -Path $BinDir -ChildPath "Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll")) if(-not (Test-PathExists -Path $files -Type Leaf)) { return } Add-Type -Path $files Write-PSFMessage -Level Verbose -Message "Testing if the cmdlet is running on a OneBox or not." -Target $Script:IsOnebox if ($Script:IsOnebox) { Write-PSFMessage -Level Verbose -Message "Machine is onebox. Will continue with DiskProvider." $diskProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $diskProviderConfiguration.AddMetadataPath($PackageDirectory) $metadataProviderFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $metadataProviderFactory.CreateDiskProvider($diskProviderConfiguration) Write-PSFMessage -Level Verbose -Message "MetadataProvider initialized." -Target $metadataProvider } else { Write-PSFMessage -Level Verbose -Message "Machine is NOT onebox. Will continue with RuntimeProvider." $runtimeProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.Runtime.RuntimeProviderConfiguration -ArgumentList $Script:PackageDirectory $metadataProviderFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $metadataProviderFactory.CreateRuntimeProvider($runtimeProviderConfiguration) Write-PSFMessage -Level Verbose -Message "MetadataProvider initialized." -Target $metadataProvider } Write-PSFMessage -Level Verbose -Message "Initializing the UpdateProvider from the MetadataProvider." $updateProvider = $metadataProvider.Updates Write-PSFMessage -Level Verbose -Message "Looping through all modules from the MetadataProvider." foreach ($obj in $metadataProvider.ModelManifest.ListModules()) { Write-PSFMessage -Level Verbose -Message "Filtering out all modules that doesn't match the model search." -Target $obj if ($obj.Name -NotLike $Model) {continue} Write-PSFMessage -Level Verbose -Message "Looping through all hotfixes for the module from the UpdateProvider." -Target $obj foreach ($objUpdate in $updateProvider.ListObjects($obj.Name)) { Write-PSFMessage -Level Verbose -Message "Reading all details for the hotfix through UpdateProvider." -Target $objUpdate $axUpdateObject = $updateProvider.Read($objUpdate) Write-PSFMessage -Level Verbose -Message "Filtering out all hotfixes that doesn't match the name search." -Target $axUpdateObject if ($axUpdateObject.Name -NotLike $Name) {continue} Write-PSFMessage -Level Verbose -Message "Filtering out all hotfixes that doesn't match the KB search." -Target $axUpdateObject if ($axUpdateObject.KBNumbers -NotLike $KB) {continue} [PSCustomObject]@{ Model = $obj.Name Hotfix = $axUpdateObject.Name Applied = $axUpdateObject.AppliedDateTime KBs = $axUpdateObject.KBNumbers } } } } end { } } ================================================ FILE: d365fo.tools/functions/get-d365installedpackage.ps1 ================================================  <# .SYNOPSIS Get installed package from Dynamics 365 Finance & Operations environment .DESCRIPTION Get installed package from the machine running the AOS service for Dynamics 365 Finance & Operations .PARAMETER Name Name of the package that you are looking for Accepts wildcards for searching. E.g. -Name "Application*Adaptor" Default value is "*" which will search for all packages .PARAMETER PackageDirectory Path to the directory containing the installed packages Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Get-D365InstalledPackage Shows the entire list of installed packages located in the default location on the machine A result set example: ApplicationFoundationFormAdaptor ApplicationPlatformFormAdaptor ApplicationSuiteFormAdaptor ApplicationWorkspacesFormAdaptor .EXAMPLE PS C:\> Get-D365InstalledPackage -Name "Application*Adaptor" Shows the list of installed packages where the name fits the search "Application*Adaptor" A result set example: ApplicationFoundationFormAdaptor ApplicationPlatformFormAdaptor ApplicationSuiteFormAdaptor ApplicationWorkspacesFormAdaptor .EXAMPLE PS C:\> Get-D365InstalledPackage -PackageDirectory "J:\AOSService\PackagesLocalDirectory" Shows the entire list of installed packages located in "J:\AOSService\PackagesLocalDirectory" on the machine A result set example: ApplicationFoundationFormAdaptor ApplicationPlatformFormAdaptor ApplicationSuiteFormAdaptor ApplicationWorkspacesFormAdaptor .NOTES Tags: PackagesLocalDirectory, Servicing, Model, Models, Package, Packages Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. #> function Get-D365InstalledPackage { [CmdletBinding()] param ( [string] $Name = "*", [string] $PackageDirectory = $Script:PackageDirectory ) Write-PSFMessage -Level Verbose -Message "Package directory is: $PackageDirectory" -Target $PackageDirectory Write-PSFMessage -Level Verbose -Message "Name is: $Name" -Target $Name $Packages = Get-ChildItem -Path $PackageDirectory -Directory -Exclude bin foreach ($obj in $Packages) { if ($obj.Name -NotLike $Name) { continue } [PSCustomObject]@{ PackageName = $obj.Name PackageDirectory = $obj.FullName } } } ================================================ FILE: d365fo.tools/functions/get-d365installedservice.ps1 ================================================  <# .SYNOPSIS Get installed D365 services .DESCRIPTION Get installed Dynamics 365 for Finance & Operations services that are installed on the machine .PARAMETER Path Path to the folder that contains the "InstallationRecords" folder .EXAMPLE PS C:\> Get-D365InstalledService This will get all installed services on the machine. .NOTES Tags: Services, Servicing, Topology Author: Mötz Jensen (@Splaxi) #> function Get-D365InstalledService { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )] [string] $Path = $Script:InstallationRecordsDir ) begin { } process { $servicePath = Join-Path $Path "ServiceModelInstallationRecords" Write-PSFMessage -Level Verbose -Message "Service installation log path is: $servicePath" -Target $servicePath $ServiceFiles = Get-ChildItem -Path $servicePath -Filter "*_current.xml" -Recurse foreach ($obj in $ServiceFiles) { [PSCustomObject]@{ ServiceName = ($obj.Name.Split("_")[0]) Version = (Select-Xml -XPath "/ServiceModelInstallationInfo/Version" -Path $obj.fullname).Node."#Text" } } } end { } } ================================================ FILE: d365fo.tools/functions/get-d365instancename.ps1 ================================================  <# .SYNOPSIS Gets the instance name .DESCRIPTION Get the instance name that is registered in the environment .EXAMPLE PS C:\> Get-D365InstanceName This will get the service name that the environment has configured .NOTES Tags: Instance, Servicing Author: Rasmus Andersen (@ITRasmus) The cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations. The call to the dll file gets HostedServiceName that is registered in the environment. #> function Get-D365InstanceName { [CmdletBinding()] param () [PSCustomObject]@{ InstanceName = "$($(Get-D365EnvironmentSettings).Infrastructure.HostedServiceName)" } } ================================================ FILE: d365fo.tools/functions/get-d365jsonservice.ps1 ================================================  <# .SYNOPSIS Get Json based service .DESCRIPTION Get Json based services that are available from a Dynamics 365 Finance & Operations environment .PARAMETER Name The name of the json service that you are looking for Default value is "*" to display all json services .PARAMETER Url URL / URI for the D365FO environment you want to access If you are working against a D365FO instance, it will be the URL / URI for the instance itself If you are working against a D365 Talent / HR instance, this will have to be "http://hr.talent.dynamics.com" .PARAMETER Tenant Azure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to access .PARAMETER ClientId The ClientId obtained from the Azure Portal when you created a Registered Application .PARAMETER ClientSecret The ClientSecret obtained from the Azure Portal when you created a Registered Application .PARAMETER RawOutput Instructs the cmdlet to include the outer structure of the response received from the endpoint The output will still be a PSCustomObject .PARAMETER OutputAsJson Instructs the cmdlet to convert the output to a Json string .EXAMPLE 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" This will get all available service groups for the D365FO instance. It will contact the D365FO instance specified in the Url parameter: "https://usnconeboxax1aos.cloud.onebox.dynamics.com". 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". It will authenticate with the specified ClientId parameter: "dea8d7a9-1602-4429-b138-111111111111". It will authenticate with the specified ClientSecret parameter: "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522". .EXAMPLE 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" This will get all available service groups for the D365FO instance, which matches the "*TS*" as a name. It will contact the D365FO instance specified in the Url parameter: "https://usnconeboxax1aos.cloud.onebox.dynamics.com". 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". It will authenticate with the specified ClientId parameter: "dea8d7a9-1602-4429-b138-111111111111". It will authenticate with the specified ClientSecret parameter: "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522". It will limit the output to only those matching the specified Name parameter: "*TS*" .EXAMPLE 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 This will get all available service groups for the D365FO instance with the outer most hierarchy. It will contact the D365FO instance specified in the Url parameter: "https://usnconeboxax1aos.cloud.onebox.dynamics.com". 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". It will authenticate with the specified ClientId parameter: "dea8d7a9-1602-4429-b138-111111111111". It will authenticate with the specified ClientSecret parameter: "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522". .EXAMPLE 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 This will get all available service groups for the D365FO instance and display the result as json. It will contact the D365FO instance specified in the Url parameter: "https://usnconeboxax1aos.cloud.onebox.dynamics.com". 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". It will authenticate with the specified ClientId parameter: "dea8d7a9-1602-4429-b138-111111111111". It will authenticate with the specified ClientSecret parameter: "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522". .NOTES Tags: DMF, OData, RestApi, Data Management Framework Author: Mötz Jensen (@Splaxi) Idea taken from http://www.ksaelen.be/wordpresses/dynamicsaxblog/2016/01/dynamics-ax-7-tip-what-services-are-exposed/ #> function Get-D365JsonService { [CmdletBinding()] [OutputType([System.String])] param ( [string] $Name = "*", [Parameter(Mandatory = $true)] [string] $Url, [Parameter(Mandatory = $true)] [string] $Tenant, [Parameter(Mandatory = $true)] [string] $ClientId, [Parameter(Mandatory = $true)] [string] $ClientSecret, [switch] $RawOutput, [switch] $OutputAsJson ) $bearerParms = @{ Resource = $Url ClientId = $ClientId ClientSecret = $ClientSecret AuthProviderUri = "https://login.microsoftonline.com/$Tenant/oauth2/token" } $bearer = Invoke-ClientCredentialsGrant @bearerParms | Get-BearerToken $headers = @{Authorization = $bearer } $Url = $Url + "/api/services" $res = Invoke-RestMethod -Method Get -Uri $Url -Headers $headers if (-not $RawOutput) { $res = $res.ServiceGroups | Where-Object { $_.Name -Like $Name -or $_.Name -eq $Name } | Sort-Object Name } else { $res.ServiceGroups = @($res.ServiceGroups | Where-Object { $_.Name -Like $Name -or $_.Name -eq $Name }) | Sort-Object Name } if ($OutputAsJson) { $res | ConvertTo-Json -Depth 10 } else { $res } } ================================================ FILE: d365fo.tools/functions/get-d365label.ps1 ================================================  <# .SYNOPSIS Get label from the label file from Dynamics 365 Finance & Operations environment .DESCRIPTION Get label from the label file from the running the Dynamics 365 Finance & Operations instance .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin Default value is fetched from the current configuration on the machine .PARAMETER LabelFileId Name / Id of the label "file" that you want to work against .PARAMETER Language Name / string representation of the language / culture you want to work against Default value is "en-US" .PARAMETER Name Name of the label that you are looking for Accepts wildcards for searching. E.g. -Name "@PRO59*" Default value is "*" which will search for all labels .EXAMPLE PS C:\> Get-D365Label -LabelFileId PRO Shows the entire list of labels that are available from the PRO label file. The language is defaulted to "en-US". .EXAMPLE PS C:\> Get-D365Label -LabelFileId PRO -Language da Shows the entire list of labels that are available from the PRO label file. Shows only all "da" (Danish) labels. .EXAMPLE PS C:\> Get-D365Label -LabelFileId PRO -Name "@PRO59*" Shows the labels available from the PRO label file where the name fits the search "@PRO59*" A result set example: Name Value Language ---- ----- -------- @PRO59 Indicates if the type of the rebate value. en-US @PRO594 Pack consumption en-US @PRO595 Pack qty now being released to production in the BOM unit. en-US @PRO596 Pack unit. en-US @PRO597 Pack proposal for release in the packing unit. en-US @PRO590 Constant pack qty en-US @PRO593 Pack proposal release in BOM unit. en-US @PRO598 Pack quantity now being released for the production in the packing unit. en-US .EXAMPLE PS C:\> Get-D365Label -LabelFileId PRO -Name "@PRO59*" -Language da,en-us Shows the labels available from the PRO label file where the name fits the search "@PRO59*". Shows for both "da" (Danish) and en-US (English) .NOTES Tags: PackagesLocalDirectory, Servicing, Language, Labels, Label Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Pedro Tornich" (twitter: @ptornich) All credits goes to him for showing how to extract these information His github repository can be found here: https://github.com/ptornich/LabelFileGenerator #> function Get-D365Label { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )] [string] $BinDir = "$Script:BinDir\bin", [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 2 )] [string] $LabelFileId, [Parameter(Mandatory = $false, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 3 )] [string[]] $Language = "en-US", [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 4 )] [string] $Name = "*" ) begin { } process { $files = @((Join-Path -Path $BinDir -ChildPath "Microsoft.Dynamics.AX.Xpp.AxShared.dll")) if (-not (Test-PathExists -Path $files -Type Leaf)) { return } Add-Type -Path $files foreach ($item in $Language) { $culture = New-Object System.Globalization.CultureInfo -ArgumentList $item Write-PSFMessage -Level Verbose -Message "Searching for label" -Target $culture $labels = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetAllLabels($LabelFileId, $culture) foreach ($itemLabel in $labels) { foreach ($key in $itemLabel.Keys) { if ($key -notlike $Name) { continue } [PSCustomObject]@{ Name = $Key Value = $itemLabel[$key] Language = $item PSTypeName = 'D365FO.TOOLS.Label' } } } } } end { } } ================================================ FILE: d365fo.tools/functions/get-d365labelfile.ps1 ================================================  <# .SYNOPSIS Get label file (ids) for packages / modules from Dynamics 365 Finance & Operations environment .DESCRIPTION Get label file (ids) for packages / modules from the machine running the AOS service for Dynamics 365 Finance & Operations .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin Default value is fetched from the current configuration on the machine .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .PARAMETER Module Name of the module that you want to work against Default value is "*" which will search for all modules .PARAMETER Name Name of the label file (id) that you are looking for Accepts wildcards for searching. E.g. -Name "Acc*Receivable*" Default value is "*" which will search for all label file (ids) .EXAMPLE PS C:\> Get-D365LabelFile Shows the entire list of label file (ids) for all installed packages / modules located in the default location on the machine .EXAMPLE PS C:\> Get-D365LabelFile -Name "Acc*Receivable*" Shows the list of label file (ids) for all installed packages / modules where the label file (ids) name fits the search "Acc*Receivable*" A result set example: LabelFileId Languages Module ----------- --------- ------ AccountsReceivable {ar-AE, ar, cs, da...} ApplicationSuite AccountsReceivable_SalesTaxCodesSA {en-US} ApplicationSuite .EXAMPLE PS C:\> Get-D365LabelFile -PackageDirectory "J:\AOSService\PackagesLocalDirectory" Shows the list of label file (ids) for all installed packages / modules located in "J:\AOSService\PackagesLocalDirectory" on the machine .NOTES Tags: PackagesLocalDirectory, Servicing, Language, Labels, Label Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Pedro Tornich" (twitter: @ptornich) All credits goes to him for showing how to extract these information His github repository can be found here: https://github.com/ptornich/LabelFileGenerator #> function Get-D365LabelFile { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )] [string] $BinDir = "$Script:BinDir\bin", [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )] [string] $PackageDirectory = $Script:PackageDirectory, [Parameter(Mandatory = $false, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 3 )] [Alias("ModuleName")] [string] $Module = "*", [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 4 )] [string] $Name = "*" ) begin { } process { $files = @((Join-Path -Path $BinDir -ChildPath "Microsoft.Dynamics.AX.Metadata.Storage.dll"), (Join-Path -Path $BinDir -ChildPath "Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll")) if(-not (Test-PathExists -Path $files -Type Leaf)) { return } Add-Type -Path $files Write-PSFMessage -Level Verbose -Message "Testing if the cmdlet is running on a OneBox or not." -Target $Script:IsOnebox if ($Script:IsOnebox) { Write-PSFMessage -Level Verbose -Message "Machine is onebox. Will continue with DiskProvider." $diskProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $diskProviderConfiguration.AddMetadataPath($PackageDirectory) $metadataProviderFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $metadataProviderFactory.CreateDiskProvider($diskProviderConfiguration) Write-PSFMessage -Level Verbose -Message "MetadataProvider initialized." -Target $metadataProvider } else { Write-PSFMessage -Level Verbose -Message "Machine is NOT onebox. Will continue with RuntimeProvider." $runtimeProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.Runtime.RuntimeProviderConfiguration -ArgumentList $Script:PackageDirectory $metadataProviderFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $metadataProviderFactory.CreateRuntimeProvider($runtimeProviderConfiguration) Write-PSFMessage -Level Verbose -Message "MetadataProvider initialized." -Target $metadataProvider } Write-PSFMessage -Level Verbose -Message "Initializing the LabelProvider from the MetadataProvider." $labelProvider = $metadataProvider.LabelFiles $res = New-Object 'System.Collections.Generic.Dictionary[string, System.Collections.ArrayList]' Write-PSFMessage -Level Verbose -Message "Looping through all modules from the MetadataProvider." foreach ($obj in $metadataProvider.ModelManifest.ListModules()) { Write-PSFMessage -Level Verbose -Message "Filtering out all modules that doesn't match the model search." -Target $obj if ($obj.Name -NotLike $Module) {continue} Write-PSFMessage -Level Verbose -Message "$($obj.Name)" $labelFiles = $labelProvider.ListObjects($obj.Name) foreach ($objLabelFile in $labelFiles) { Write-PSFMessage -Level Verbose -Message "$($objLabelFile)" if($objLabelFile -like "*.*") { $chars = $objLabelFile.ToCharArray() $chars[$objLabelFile.LastIndexOf(".")] = "_" $objLabelFile = $chars -join "" } $labelId = $objLabelFile.Substring(0, $objLabelFile.LastIndexOf("_")) $langString = $objLabelFile.Substring($objLabelFile.LastIndexOf("_") + 1) if ($labelId -NotLike $Name) {continue} if(-not ($res.ContainsKey($labelId))) { $null = $res.Add($labelId, (New-object -TypeName "System.Collections.ArrayList")) } $null = $res[$labelId].Add($langString) } foreach ($item in $res.Keys) { [PSCustomObject]@{ LabelFileId = $item Languages = $res[$item] Module = $obj.Name } } } } end { } } ================================================ FILE: d365fo.tools/functions/get-d365language.ps1 ================================================  <# .SYNOPSIS Get installed languages from Dynamics 365 Finance & Operations environment .DESCRIPTION Get installed languages from the running the Dynamics 365 Finance & Operations instance .PARAMETER BinDir Path to the directory containing the BinDir and its assemblies Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .PARAMETER Name Name of the language that you are looking for Accepts wildcards for searching. E.g. -Name "fr*" Default value is "*" which will search for all languages .EXAMPLE PS C:\> Get-D365Language Shows the entire list of installed languages that are available from the running instance .EXAMPLE PS C:\> Get-D365Language -Name "fr*" Shows the list of installed languages where the name fits the search "fr*" A result set example: fr French fr-BE French (Belgium) fr-CA French (Canada) fr-CH French (Switzerland) .NOTES Tags: PackagesLocalDirectory, Servicing, Language, Labels, Label Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Pedro Tornich" (twitter: @ptornich) All credits goes to him for showing how to extract these information His github repository can be found here: https://github.com/ptornich/LabelFileGenerator #> function Get-D365Language { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )] [string] $BinDir = "$Script:BinDir\bin", [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )] [string] $Name = "*" ) begin { } process { $files = @((Join-Path -Path $BinDir -ChildPath "Microsoft.Dynamics.AX.Xpp.AxShared.dll")) if(-not (Test-PathExists -Path $files -Type Leaf)) { return } Add-Type -Path $files $languages = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetInstalledLanguages() foreach ($obj in $languages) { Write-PSFMessage -Level Verbose -Message "Filtering out all modules that doesn't match the model search." -Target $obj if ($obj -NotLike $Name) {continue} $lang = New-Object System.Globalization.CultureInfo -ArgumentList $obj [PSCustomObject]@{ Name = $obj LanguageName = $lang.DisplayName } } } end { } } ================================================ FILE: d365fo.tools/functions/get-d365lcsapiconfig.ps1 ================================================  <# .SYNOPSIS Get the LCS configuration details .DESCRIPTION Get the LCS configuration details from the configuration store All settings retrieved from this cmdlets is to be considered the default parameter values across the different cmdlets .PARAMETER OutputAsHashtable Instruct the cmdlet to return a hashtable object .EXAMPLE PS C:\> Get-D365LcsApiConfig This will output the current LCS API configuration. The object returned will be a PSCustomObject. .EXAMPLE PS C:\> Get-D365LcsApiConfig -OutputAsHashtable This will output the current LCS API configuration. The object returned will be a Hashtable. .LINK Get-D365LcsApiToken .LINK Get-D365LcsAssetValidationStatus .LINK Get-D365LcsDeploymentStatus .LINK Invoke-D365LcsApiRefreshToken .LINK Invoke-D365LcsDeployment .LINK Invoke-D365LcsUpload .LINK Set-D365LcsApiConfig .NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, ClientId Author: Mötz Jensen (@Splaxi) #> function Get-D365LcsApiConfig { [CmdletBinding()] [OutputType()] param ( [switch] $OutputAsHashtable ) Invoke-TimeSignal -Start $res = [Ordered]@{} Write-PSFMessage -Level Verbose -Message "Extracting all the LCS configuration and building the result object." foreach ($config in Get-PSFConfig -FullName "d365fo.tools.lcs.*") { $propertyName = $config.FullName.ToString().Replace("d365fo.tools.lcs.", "") $res.$propertyName = $config.Value } if($OutputAsHashtable) { $res } else { [PSCustomObject]$res } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/get-d365lcsapitoken.ps1 ================================================  <# .SYNOPSIS Get a valid OAuth 2.0 access token for LCS .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 .PARAMETER ClientId The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal Default value can be configured using Set-D365LcsApiConfig .PARAMETER Username The username of the account that you want to impersonate It can either be your personal account or a service account .PARAMETER Password The password of the account that you want to impersonate .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-D365LcsApiToken -ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" -Username "serviceaccount@domain.com" -Password "TopSecretPassword" -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will obtain a valid OAuth 2.0 access token from Azure Active Directory. The ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" is used in the OAuth 2.0 Grant Flow to authenticate. 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". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .EXAMPLE 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 This will obtain a valid OAuth 2.0 access token from Azure Active Directory. The ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" is used in the OAuth 2.0 Grant Flow to authenticate. 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". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). The output object received from Get-D365LcsApiToken is piped directly to Set-D365LcsApiConfig. 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. 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. .EXAMPLE PS C:\> Get-D365LcsApiToken -Username "serviceaccount@domain.com" -Password "TopSecretPassword" This will obtain a valid OAuth 2.0 access token from Azure Active Directory. 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". All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsApiToken -Username "serviceaccount@domain.com" -Password "TopSecretPassword" | Set-D365LcsApiConfig This will obtain a valid OAuth 2.0 access token from Azure Active Directory and save the needed details. 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". The output object received from Get-D365LcsApiToken is piped directly to Set-D365LcsApiConfig. Set-D365LcsApiConfig will save the access_token(BearerToken), refresh_token(RefreshToken) and expires_on(ActiveTokenExpiresOn). All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .LINK Get-D365LcsApiConfig .LINK Get-D365LcsAssetValidationStatus .LINK Get-D365LcsDeploymentStatus .LINK Invoke-D365LcsApiRefreshToken .LINK Invoke-D365LcsDeployment .LINK Invoke-D365LcsUpload .LINK Set-D365LcsApiConfig .NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token Author: Mötz Jensen (@Splaxi) #> function Get-D365LcsApiToken { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingUserNameAndPassWordParams", "")] [CmdletBinding()] [OutputType()] param( [Parameter(Mandatory = $false)] [string] $ClientId = $Script:LcsApiClientId, [Parameter(Mandatory = $true)] [string] $Username, [Parameter(Mandatory = $true)] [string] $Password, [Parameter(Mandatory = $false)] [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [switch] $EnableException ) Invoke-TimeSignal -Start $tokenParms = @{ } $tokenParms.Resource = $LcsApiUri $tokenParms.ClientId = $ClientId $tokenParms.Username = $Username $tokenParms.Password = $Password $tokenParms.Scope = "openid" $tokenParms.AuthProviderUri = $Script:AADOAuthEndpoint Invoke-PasswordGrant @tokenParms Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/get-d365lcsassetfile.ps1 ================================================  <# .SYNOPSIS Get file from the Asset library inside the LCS project .DESCRIPTION Get the available files from the Asset Library in LCS project .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig .PARAMETER FileType Type of file you want to list from the LCS Asset Library Valid options: "Model" "Process Data Package" "Software Deployable Package" "GER Configuration" "Data Package" "PowerBI Report Model" "E-Commerce Package" "NuGet Package" "Retail Self-Service Package" "Commerce Cloud Scale Unit Extension" Default value is "Software Deployable Package" .PARAMETER AssetName Name of the asset that you are looking for Accepts wildcards for searching. E.g. -AssetName "*ISV*" Default value is "*" which will search for all assets via the Name property .PARAMETER AssetVersion Version of the Asset file that you are looking for It does a simple compare against the response from LCS and only lists the ones that matches Accepts wildcards for searching. E.g. -AssetVersion "*ISV*" Default value is "*" which will search for all files .PARAMETER AssetFilename Name of the file that you are looking for Accepts wildcards for searching. E.g. -AssetFilename "*ISV*" Default value is "*" which will search for all files via the FileName property .PARAMETER AssetDescription Name of the file that you are looking for Accepts wildcards for searching. E.g. -AssetDescription "*ISV*" Default value is "*" which will search for all files via the FileDescription property .PARAMETER AssetId Id of the file that you are looking for Accepts wildcards for searching. E.g. -AssetId "*ISV*" Default value is "*" which will search for all files via the AssetId property .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER Latest Instruct the cmdlet to only fetch the latest file from the Asset Library from LCS .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-D365LcsAssetFile -ProjectId 123456789 -FileType SoftwareDeployablePackage -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will list all Software Deployable Packages. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .EXAMPLE PS C:\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage This will list all Software Deployable Packages. It will search for SoftwareDeployablePackage by using the FileType parameter. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetFilename "*MAIN*" This will list all Software Deployable Packages, that matches the "*MAIN*" search pattern in the AssetFilename. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetFilename "*MAIN*" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetName "*MAIN*" This will list all Software Deployable Packages, that matches the "*MAIN*" search pattern in the AssetName. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetName "*MAIN*" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetDescription "*TEST*" This will list all Software Deployable Packages, that matches the "*TEST*" search pattern in the AssetDescription. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetDescription "*TEST*" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetId "500dd860-eacf-4e04-9f18-f9c8fe1d8e03" This will list all Software Deployable Packages, that matches the "500dd860-eacf-4e04-9f18-f9c8fe1d8e03" search pattern in the AssetId. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetId "500dd860-eacf-4e04-9f18-f9c8fe1d8e03" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -Latest | Invoke-D365AzCopyTransfer -DestinationUri C:\Temp\d365fo.tools -FileName "Main.zip" -ShowOriginalProgress This will download the latest Software Deployable Package from the Asset Library in LCS onto your on machine. It will list Software Deployable Packages based on the FileType parameter. It will list the latest (newest) Software Deployable Package. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -RetryTimeout "00:01:00" This will list all Software Deployable Packages, and allow for the cmdlet to retry for no more than 1 minute. It will search for SoftwareDeployablePackage by using the FileType parameter. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .LINK Get-D365LcsApiConfig .LINK Get-D365LcsApiToken .LINK Invoke-D365LcsApiRefreshToken .LINK Set-D365LcsApiConfig .LINK Get-D365LcsSharedAssetFile .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-D365LcsAssetFile { [CmdletBinding()] [OutputType()] param ( [int] $ProjectId = $Script:LcsApiProjectId, [LcsAssetFileType] $FileType = [LcsAssetFileType]::SoftwareDeployablePackage, [string] $AssetName = "*", [string] $AssetVersion = "*", [string] $AssetFilename = "*", [string] $AssetDescription = "*", [string] $AssetId = "*", [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [Alias('GetLatest')] [switch] $Latest, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) Invoke-TimeSignal -Start if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } $assets = Get-LcsAssetFileV2 -BearerToken $BearerToken -ProjectId $ProjectId -LcsApiUri $LcsApiUri -FileType $([int]$FileType) -RetryTimeout $RetryTimeout if (Test-PSFFunctionInterrupt) { return } if ($Latest) { $assets | Sort-Object -Property "ModifiedDate" -Descending | Select-Object -First 1 | Select-PSFObject -TypeName "D365FO.TOOLS.Lcs.Asset.File" "*", "Id as AssetId" } else { foreach ($obj in $assets) { if ($obj.Name -NotLike $AssetName) { continue } if ($obj.Version -NotLike $AssetVersion) { continue } if ($obj.FileName -NotLike $AssetFilename) { continue } if ($obj.FileDescription -NotLike $AssetDescription) { continue } if ($obj.Id -NotLike $AssetId) { continue } $obj | Select-PSFObject -TypeName "D365FO.TOOLS.Lcs.Asset.File" "*", "Id as AssetId" } } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/get-d365lcsassetvalidationstatus.ps1 ================================================  <# .SYNOPSIS Get the validation status from LCS .DESCRIPTION Get the validation status for a given file in the Asset Library in LCS .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER AssetId The unique id of the asset / file that you are trying to deploy from LCS .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER WaitForValidation Instruct the cmdlet to wait for the validation process to complete The cmdlet will sleep for 60 seconds, before requesting the status of the validation process from LCS .PARAMETER SleepInSeconds Time in seconds that you want the cmdlet to use as the sleep timer between each request against the LCS endpoint Default value is 60 .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-D365LcsAssetValidationStatus -ProjectId 123456789 -BearerToken "JldjfafLJdfjlfsalfd..." -AssetId "958ae597-f089-4811-abbd-c1190917eaae" -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will check the validation status for the file in the Asset Library. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. 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. The request will authenticate with the BearerToken "Bearer JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .EXAMPLE PS C:\> Get-D365LcsAssetValidationStatus -AssetId "958ae597-f089-4811-abbd-c1190917eaae" This will check the validation status for the file in the Asset Library. 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. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsAssetValidationStatus -AssetId "958ae597-f089-4811-abbd-c1190917eaae" -WaitForValidation This will check the validation status for the file in the Asset Library. 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. The cmdlet will every 60 seconds contact the LCS API endpoint and check if the status of the validation is either success or failure. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Invoke-D365LcsUpload -FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip" | Get-D365LcsAssetValidationStatus -WaitForValidation This will start the upload of a file to the Asset Library and check the validation status for the file in the Asset Library. The file that will be uploaded is based on the FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip". The output object received from Invoke-D365LcsUpload is piped directly to Get-D365LcsAssetValidationStatus. The cmdlet will every 60 seconds contact the LCS API endpoint and check if the status of the validation is either success or failure. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsAssetValidationStatus -AssetId "958ae597-f089-4811-abbd-c1190917eaae" -RetryTimeout "00:01:00" 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. 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. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .LINK Get-D365LcsApiConfig .LINK Get-D365LcsApiToken .LINK Get-D365LcsDeploymentStatus .LINK Invoke-D365LcsApiRefreshToken .LINK Invoke-D365LcsDeployment .LINK Invoke-D365LcsUpload .LINK Set-D365LcsApiConfig .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-D365LcsAssetValidationStatus { [CmdletBinding()] [OutputType()] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string] $AssetId, [int] $ProjectId = $Script:LcsApiProjectId, [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [switch] $WaitForValidation, [int] $SleepInSeconds = 60, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) process { Invoke-TimeSignal -Start if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } do { Write-PSFMessage -Level Verbose -Message "Sleeping before hitting the LCS API for Asset Validation Status" Start-Sleep -Seconds $SleepInSeconds $status = Get-LcsAssetValidationStatusV2 -BearerToken $BearerToken -ProjectId $ProjectId -AssetId $AssetId -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout if (Test-PSFFunctionInterrupt) { return } } while (($status.DisplayStatus -eq "Process") -and $WaitForValidation) Invoke-TimeSignal -End $status | Select-PSFObject "ID as AssetId", "DisplayStatus as Status" } } ================================================ FILE: d365fo.tools/functions/get-d365lcsdatabasebackups.ps1 ================================================  <# .SYNOPSIS Get database backups from LCS project .DESCRIPTION Get the available database backups from the Asset Library in LCS project .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER Latest Instruct the cmdlet to only fetch the latest file from the Azure Storage Account .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-D365LcsDatabaseBackups -ProjectId 123456789 -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will get all available database backups from the Asset Library inside LCS. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The request will authenticate with the BearerToken "Bearer JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .EXAMPLE PS C:\> Get-D365LcsDatabaseBackups This will get all available database backups from the Asset Library inside LCS. It will use default values for all parameters. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsDatabaseBackups -Latest This will get the latest available database backup from the Asset Library inside LCS. It will use default values for all parameters. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsDatabaseBackups -Latest -RetryTimeout "00:01:00" 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. It will use default values for all parameters. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .LINK Get-D365LcsApiConfig .LINK Get-D365LcsApiToken .LINK Invoke-D365LcsApiRefreshToken .LINK Set-D365LcsApiConfig .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-D365LcsDatabaseBackups { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] [OutputType()] param ( [int] $ProjectId = $Script:LcsApiProjectId, [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [Alias('GetLatest')] [switch] $Latest, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) Invoke-TimeSignal -Start if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } $backups = Get-LcsDatabaseBackupsV2 -BearerToken $BearerToken -ProjectId $ProjectId -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout if (Test-PSFFunctionInterrupt) { return } if ($Latest) { $backups.DatabaseAssets | Sort-Object -Property "CreatedDateTime" -Descending | Select-Object -First 1 } else { $backups.DatabaseAssets } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/get-d365lcsdatabaseoperationstatus.ps1 ================================================  <# .SYNOPSIS Get the status of a database operation from LCS .DESCRIPTION Get the current status of a database operation against an environment from a LCS project .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER OperationActivityId The unique id of the operaction activity that identitfies the database operation It will be part of the output from the different Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets .PARAMETER EnvironmentId The unique id of the environment that you want to work against The Id can be located inside the LCS portal .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER WaitForCompletion Instruct the cmdlet to wait for the deployment process to complete The cmdlet will sleep for 300 seconds, before requesting the status of the deployment process from LCS .PARAMETER SleepInSeconds Time in seconds that you want the cmdlet to use as the sleep timer between each request against the LCS endpoint Default value is 300 .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-D365LcsDatabaseOperationStatus -ProjectId 123456789 -OperationActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will check the database operation status of a specific OperationActivityId against an environment. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .EXAMPLE PS C:\> Get-D365LcsDatabaseOperationStatus -OperationActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" This will check the database operation status of a specific OperationActivityId against an environment. The OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsDatabaseOperationStatus -OperationActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -WaitForCompletion This will check the database operation status of a specific OperationActivityId against an environment. The OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. 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. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsDatabaseOperationStatus -OperationActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -RetryTimeout "00:01:00" 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. The OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .LINK Get-D365LcsApiConfig .LINK Get-D365LcsApiToken .LINK Get-D365LcsAssetValidationStatus .LINK Invoke-D365LcsApiRefreshToken .LINK Invoke-D365LcsDeployment .LINK Invoke-D365LcsUpload .LINK Set-D365LcsApiConfig .NOTES Tags: Environment, Config, Configuration, LCS, Database backup, Api, Backup, Restore, Refresh Author: Mötz Jensen (@Splaxi) #> function Get-D365LcsDatabaseOperationStatus { [CmdletBinding()] [OutputType('PSCustomObject')] param( [int] $ProjectId = $Script:LcsApiProjectId, [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('ActivityId')] [string] $OperationActivityId, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('SourceEnvironmentId')] [string] $EnvironmentId, [Parameter(Mandatory = $false)] [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [switch] $WaitForCompletion, [int] $SleepInSeconds = 300, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) process { Invoke-TimeSignal -Start if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } do { Write-PSFMessage -Level Verbose -Message "Sleeping before hitting the LCS API for Deployment Status" Start-Sleep -Seconds $SleepInSeconds $databaseOperationStatus = Get-LcsDatabaseOperationStatusV2 -BearerToken $BearerToken -ProjectId $ProjectId -OperationActivityId $OperationActivityId -EnvironmentId $EnvironmentId -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout Write-PSFMessage -Level Verbose -Message "Database Operation Status is: $($databaseOperationStatus.OperationStatus)" if (Test-PSFFunctionInterrupt) { return } } while ((($databaseOperationStatus.OperationStatus -eq "InProgress") -or ($databaseOperationStatus.OperationStatus -eq "NotStarted") -or ($databaseOperationStatus.OperationStatus -eq "RollbackInProgress")) -and $WaitForCompletion) Invoke-TimeSignal -End $databaseOperationStatus | Select-PSFObject * -TypeName "D365FO.TOOLS.LCS.Database.Operation.Status" } } ================================================ FILE: d365fo.tools/functions/get-d365lcsdeploymentstatus.ps1 ================================================  <# .SYNOPSIS Get the Deployment status from LCS .DESCRIPTION Get the Deployment status for activity against an environment from the Dynamics LCS Portal .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER ActivityId The unique id of the action that you started from the Invoke-D365LcsDeployment cmdlet .PARAMETER EnvironmentId The unique id of the environment that you want to work against The Id can be located inside the LCS portal .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER WaitForCompletion Instruct the cmdlet to wait for the deployment process to complete The cmdlet will sleep for 300 seconds, before requesting the status of the deployment process from LCS .PARAMETER SleepInSeconds Time in secounds that you want the cmdlet to use as the sleep timer between each request against the LCS endpoint Default value is 300 .PARAMETER FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-D365LcsDeploymentStatus -ProjectId 123456789 -ActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -BearerToken "Bearer JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will check the deployment status of specific activity against an environment. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "Bearer JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .EXAMPLE PS C:\> Get-D365LcsDeploymentStatus -ActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" This will check the deployment status of specific activity against an environment. The activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsDeploymentStatus -ActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -WaitForCompletion This will check the deployment status of specific activity against an environment. The activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The cmdlet will every 300 seconds contact the LCS API endpoint and check if the status of the deployment is either success or failure. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsDeploymentStatus -ActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -RetryTimeout "00:01:00" 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. The activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .LINK Get-D365LcsApiConfig .LINK Get-D365LcsApiToken .LINK Get-D365LcsAssetValidationStatus .LINK Invoke-D365LcsApiRefreshToken .LINK Invoke-D365LcsDeployment .LINK Invoke-D365LcsUpload .LINK Set-D365LcsApiConfig .NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deploy Author: Mötz Jensen (@Splaxi) #> function Get-D365LcsDeploymentStatus { [CmdletBinding()] [OutputType('PSCustomObject')] param( [Parameter(Mandatory = $false)] [int] $ProjectId = $Script:LcsApiProjectId, [Parameter(Mandatory = $false)] [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('ActionHistoryId')] [string] $ActivityId, [Parameter(Mandatory = $true)] [string] $EnvironmentId, [Parameter(Mandatory = $false)] [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [switch] $WaitForCompletion, [int] $SleepInSeconds = 300, [switch] $FailOnErrorMessage, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) process { Invoke-TimeSignal -Start if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } do { Write-PSFMessage -Level Verbose -Message "Sleeping before hitting the LCS API for Deployment Status" Start-Sleep -Seconds $SleepInSeconds $deploymentStatus = Get-LcsDeploymentStatusV2 -BearerToken $BearerToken -ProjectId $ProjectId -ActivityId $ActivityId -EnvironmentId $EnvironmentId -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout if (Test-PSFFunctionInterrupt) { return } if ($FailOnErrorMessage -and $deploymentStatus.ErrorMessage) { $messageString = "The request against LCS succeeded, but the response was an error message for the operation: $($deploymentStatus.ErrorMessage)." $errorMessagePayload = "`r`n$($deploymentStatus | ConvertTo-Json)" Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus } } while ((($deploymentStatus.OperationStatus -eq "InProgress") -or ($deploymentStatus.OperationStatus -eq "NotStarted") -or ($deploymentStatus.OperationStatus -eq "PreparingEnvironment")) -and $WaitForCompletion) Invoke-TimeSignal -End $deploymentStatus | Select-PSFObject * -TypeName "D365FO.TOOLS.LCS.Deployment.Operation.Status" } } ================================================ FILE: d365fo.tools/functions/get-d365lcsenvironmenthistory.ps1 ================================================  <# .SYNOPSIS Get history for a given environment within a LCS project .DESCRIPTION Get history details for a given environment from within a LCS project There can be multiple pages of data, which requires you to use the TraverseAllPages parameter, if you want all data to be shown .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER EnvironmentId Id of the environment that you want to be working against .PARAMETER TraverseAllPages Instruct the cmdlet to fetch all pages, until there isn't more data available This can be a slow operation, as it has to call the LCS API multiple times, fetching a single page per call .PARAMETER FirstPages Instruct the cmdlet how many pages that you want it to retrieve from the LCS API Can only be used in combination with -TraverseAllPages The default value is: 99 pages, which should be more than enough Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-D365LcsEnvironmentHistory -ProjectId "123456789" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" This will list the first page of Environment History Data from the LCS API. The LCS project is identified by the ProjectId "123456789", which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. A result set example: Name : Service Update - 10.0.19 Type : SFBinaryHotfix TypeDisplay : Binary hotfix StartDateTimeUTC : 2021-07-11T00:01:57.423 EndDateTimeUTC : 2021-07-11T05:01:12.97 Status : Completed ActivityId : e3509860-61d4-4003-9b45-6ea7d89aea30 EnvironmentId : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e ProjectId : 123456789 Name : Refresh database Type : SFSourceDbToSandbox TypeDisplay : Refresh database StartDateTimeUTC : 2021-06-06T15:17:48.87 EndDateTimeUTC : 2021-06-06T16:33:40.367 Status : Completed ActivityId : e3509860-61d4-4003-9b45-6ea7d89aea31 EnvironmentId : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e ProjectId : 123456789 Name : Export database Type : SFExportSandboxDb TypeDisplay : Export database StartDateTimeUTC : 2021-04-27T22:08:01.103 EndDateTimeUTC : 2021-04-28T23:30:06.623 Status : RollbackCompleted ActivityId : e3509860-61d4-4003-9b45-6ea7d89aea32 EnvironmentId : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e ProjectId : 123456789 Name : Main_2021.1.1.1 Type : SFApplicationHotfix TypeDisplay : Application deployable package StartDateTimeUTC : 2021-03-04T21:44:20.793 EndDateTimeUTC : 2021-03-04T22:48:17.303 Status : Completed ActivityId : e3509860-61d4-4003-9b45-6ea7d89aea33 EnvironmentId : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e ProjectId : 123456789 .EXAMPLE PS C:\> Get-D365LcsEnvironmentHistory -ProjectId "123456789" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -TraverseAllPages This will list the all the pages of Environment History Data from the LCS API. The LCS project is identified by the ProjectId "123456789", which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The cmdlet will TraverseAllPages from the LCS API. It will use the default value for the maximum number of pages to return, 99 pages. TraverseAllPages will increase the request time for completion, based on how many entries there is in the history. Please be patient and let the system work for you. Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint .EXAMPLE PS C:\> Get-D365LcsEnvironmentHistory -ProjectId "123456789" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -TraverseAllPages -FirstPages 2 This will list the all the pages of Environment History Data from the LCS API. The LCS project is identified by the ProjectId "123456789", which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The cmdlet will TraverseAllPages from the LCS API. The cmdlet will be fetching the FirstPages 2, to limit the output from the cmdlet to only the newest 2 pages. TraverseAllPages will increase the request time for completion, based on how many entries there is in the history. Please be patient and let the system work for you. Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-D365LcsEnvironmentHistory { [CmdletBinding(DefaultParameterSetName = 'Default')] [OutputType('PSCustomObject')] param( [int] $ProjectId = $Script:LcsApiProjectId, [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [Parameter(Mandatory = $true)] [string] $EnvironmentId, [Parameter(ParameterSetName = 'Pagination')] [switch] $TraverseAllPages, [Parameter(ParameterSetName = 'Pagination')] [int] $FirstPages = 99, [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [switch] $FailOnErrorMessage, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) process { Invoke-TimeSignal -Start if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } $parms = @{} $parms.ProjectId = $ProjectId $parms.BearerToken = $BearerToken $parms.EnvironmentId = $EnvironmentId $parms.LcsApiUri = $LcsApiUri $parms.RetryTimeout = $RetryTimeout $parms.EnableException = $EnableException [System.Collections.Generic.List[System.Object]] $resArray = @() $page = 1 do { $history = Get-LcsEnvironmentHistory @parms $resArray.AddRange($history.Data) if ($history.ResultHasMorePages -eq $true) { $page += 1 $parms.Page = $page } if (Test-PSFFunctionInterrupt) { return } if ($FailOnErrorMessage -and $deploymentStatus.ErrorMessage) { $messageString = "The request against LCS succeeded, but the response was an error message for the operation: $($deploymentStatus.ErrorMessage)." $errorMessagePayload = "`r`n$($deploymentStatus | ConvertTo-Json)" Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus } } while (($history.ResultHasMorePages -eq $true) -and $TraverseAllPages -and $page -le $FirstPages) $res = $null if ($resArray.Count -gt 0) { $res = $resArray.ToArray() } Invoke-TimeSignal -End $res | Select-PSFObject * -TypeName "D365FO.TOOLS.LCS.Environment.History" } } ================================================ FILE: d365fo.tools/functions/get-d365lcsenvironmentmetadata.ps1 ================================================  <# .SYNOPSIS Get LCS environment meta data from within a project .DESCRIPTION Get all meta data details for environments from within a LCS project It supports listing all environments, but also supports single / specific environments by searching based on EnvironmentId or EnvironmentName .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER EnvironmentId Id of the environment that you want to be working against .PARAMETER EnvironmentName Name of the environment that you want to be working against .PARAMETER TraverseAllPages Instruct the cmdlet to fetch all pages, until there isn't more data available This can be a slow operation, as it has to call the LCS API multiple times, fetching a single page per call .PARAMETER FirstPages Instruct the cmdlet how many pages that you want it to retrieve from the LCS API Can only be used in combination with -TraverseAllPages The default value is: 99 pages, which should be more than enough Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-D365LcsEnvironmentMetadata -ProjectId "123456789" This will show metadata for every available environment from the LCS project. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The request time for completion is directly impacted by the number of environments within the LCS project. Please be patient and let the system work for you. 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. A result set example (Tier1): EnvironmentId : c6566087-23bd-4561-8247-4d7f4efd3172 EnvironmentName : DevBox-01 ProjectId : 123456789 EnvironmentInfrastructure : CustomerManaged EnvironmentType : DevTestDev EnvironmentGroup : Primary EnvironmentProduct : Finance and Operations EnvironmentEndpointBaseUrl : https://devbox-4d7f4efd3172devaos.cloudax.dynamics.com/ DeploymentState : Stopped TopologyDisplayName : Finance and Operations - Develop (10.0.18 with Platform update 42) CurrentApplicationBuildVersion : 10.0.793.41 CurrentApplicationReleaseName : 10.0.18 CurrentPlatformReleaseName : Update42 CurrentPlatformVersion : 7.0.5968.16999 DeployedOnUTC : 7/5/2021 11:19 AM CloudStorageLocation : West Europe DisasterRecoveryLocation : North Europe DeploymentStatusDisplay : Stopped CanStart : True CanStop : False A result set example (Tier2+): EnvironmentId : e7c53b85-8b6a-4ab9-8985-1e1ea89a0f0a EnvironmentName : Contoso-SIT ProjectId : 123456789 EnvironmentInfrastructure : SelfService EnvironmentType : Sandbox EnvironmentGroup : Primary EnvironmentProduct : Finance and Operations EnvironmentEndpointBaseUrl : https://Contoso-SIT.sandbox.operations.dynamics.com/ DeploymentState : Finished TopologyDisplayName : AXHA CurrentApplicationBuildVersion : 10.0.761.10019 CurrentApplicationReleaseName : 10.0.17 CurrentPlatformReleaseName : PU41 CurrentPlatformVersion : 7.0.5934.35741 DeployedOnUTC : 4/1/2020 9:35 PM CloudStorageLocation : West Europe DisasterRecoveryLocation : DeploymentStatusDisplay : Deployed CanStart : False CanStop : False A result set example (PROD): EnvironmentId : a8aab4f4-d4f3-41f0-af80-54cea83b50d2 EnvironmentName : Contoso-PROD ProjectId : 123456789 EnvironmentInfrastructure : SelfService EnvironmentType : Production EnvironmentGroup : Primary EnvironmentProduct : Finance and Operations EnvironmentEndpointBaseUrl : https://Contoso-PROD.operations.dynamics.com/ DeploymentState : Finished TopologyDisplayName : AXHA CurrentApplicationBuildVersion : 10.0.886.48 CurrentApplicationReleaseName : 10.0.20 CurrentPlatformReleaseName : PU44 CurrentPlatformVersion : 7.0.6060.45 DeployedOnUTC : 4/9/2020 12:11 PM CloudStorageLocation : West Europe DisasterRecoveryLocation : DeploymentStatusDisplay : Deployed CanStart : False CanStop : False .EXAMPLE PS C:\> Get-D365LcsEnvironmentMetadata -ProjectId "123456789" -TraverseAllPages This will show metadata for every available environment from the LCS project, across multiple pages. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. It will use the default value for the maximum number of pages to return, 99 pages. TraverseAllPages will increase the request time for completion, based on how many entries there is in the history. Please be patient and let the system work for you. Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint .EXAMPLE PS C:\> Get-D365LcsEnvironmentMetadata -ProjectId "123456789" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" This will show metadata for every available environment from the LCS project. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. .EXAMPLE PS C:\> Get-D365LcsEnvironmentMetadata -ProjectId "123456789" -EnvironmentName "Contoso-SIT" This will show metadata for every available environment from the LCS project. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentName "Contoso-SIT", which can be obtained in the LCS portal. .EXAMPLE PS C:\> Get-D365LcsEnvironmentMetadata -ProjectId "123456789" -TraverseAllPages -FirstPages 2 This will show metadata for every available environment from the LCS project, across multiple pages. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. It will use the default value for the maximum number of pages to return, 99 pages. The cmdlet will be fetching the FirstPages 2, to limit the output from the cmdlet to only the newest 2 pages. TraverseAllPages will increase the request time for completion, based on how many entries there is in the history. Please be patient and let the system work for you. Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-D365LcsEnvironmentMetadata { [CmdletBinding(DefaultParameterSetName = 'Default')] [OutputType('PSCustomObject')] param( [int] $ProjectId = $Script:LcsApiProjectId, [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [Parameter(ParameterSetName = 'SearchByEnvironmentId')] [string] $EnvironmentId, [Parameter(ParameterSetName = 'SearchByEnvironmentName')] [string] $EnvironmentName, [Parameter(ParameterSetName = 'Pagination')] [switch] $TraverseAllPages, [Parameter(ParameterSetName = 'Pagination')] [int] $FirstPages = 99, [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [switch] $FailOnErrorMessage, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) process { Invoke-TimeSignal -Start if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } $parms = @{} $parms.ProjectId = $ProjectId $parms.BearerToken = $BearerToken $parms.LcsApiUri = $LcsApiUri $parms.RetryTimeout = $RetryTimeout $parms.EnableException = $EnableException if ($PSCmdlet.ParameterSetName -eq "SearchByEnvironmentId") { $parms.EnvironmentId = $EnvironmentId } elseif ($PSCmdlet.ParameterSetName -eq "SearchByEnvironmentName") { $parms.EnvironmentName = $EnvironmentName } [System.Collections.Generic.List[System.Object]] $resArray = @() $page = 1 do { $metadata = Get-LcsEnvironmentMetadata @parms $resArray.AddRange($metadata.Data) if ($metadata.ResultHasMorePages -eq $true) { $page += 1 $parms.Page = $page } if (Test-PSFFunctionInterrupt) { return } if ($FailOnErrorMessage -and $deploymentStatus.ErrorMessage) { $messageString = "The request against LCS succeeded, but the response was an error message for the operation: $($deploymentStatus.ErrorMessage)." $errorMessagePayload = "`r`n$($deploymentStatus | ConvertTo-Json)" Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus } } while (($metadata.ResultHasMorePages -eq $true) -and $TraverseAllPages -and $page -le $FirstPages) $res = $null if ($resArray.Count -gt 0) { $res = $resArray.ToArray() } Invoke-TimeSignal -End $res | Select-PSFObject * -TypeName "D365FO.TOOLS.LCS.Environment.Metadata" } } ================================================ FILE: d365fo.tools/functions/get-d365lcsenvironmentrsatcertificate.ps1 ================================================  <# .SYNOPSIS Get LCS environment rsat certificate from within a project .DESCRIPTION Download and persist the active rsat certificate from environments from within a LCS project .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER EnvironmentId Id of the environment that you want to be working against .PARAMETER OutputPath Path to where you want the certificate files to be saved The default value is: "c:\temp\d365fo.tools\RsatCert\" .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-D365LcsEnvironmentRsatCertificate -ProjectId "123456789" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" This will download the active rsat certificate file for the environment from the LCS project. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. A result set example: Path : c:\temp\d365fo.tools\RsatCert\RSATCertificate_ABC-UAT_20240101-012030 CerFile : C:\temp\d365fo.tools\RsatCert\RSATCertificate_ABC-UAT_20240101-012030\RSATCertificate_ABC-UAT_20240101-012030.cer PfxFile : C:\temp\d365fo.tools\RsatCert\RSATCertificate_ABC-UAT_20240101-012030\RSATCertificate_ABC-UAT_20240101-012030.pfx FileName : RSATCertificate_ABC-UAT_20240101-012030.zip Password : 9zbPiLMTk676mkq5FvqQ .EXAMPLE PS C:\> Get-D365LcsEnvironmentRsatCertificate -ProjectId "123456789" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" | Import-D365RsatSelfServiceCertificates This will download the active rsat certificate file for the environment from the LCS project. The resulting files are then imported into the certificate store on the local machine. .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-D365LcsEnvironmentRsatCertificate { [CmdletBinding(DefaultParameterSetName = 'Default')] [OutputType('PSCustomObject')] param( [int] $ProjectId = $Script:LcsApiProjectId, [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [Parameter(Mandatory = $true)] [string] $EnvironmentId, [string] $OutputPath = $(Join-Path $Script:DefaultTempPath "RsatCert"), [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [switch] $FailOnErrorMessage, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) process { Invoke-TimeSignal -Start if (-not (Test-PathExists -Path $OutputPath -Type Container -Create)) { return } if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } $parms = @{} $parms.ProjectId = $ProjectId $parms.BearerToken = $BearerToken $parms.LcsApiUri = $LcsApiUri $parms.RetryTimeout = $RetryTimeout $parms.EnableException = $EnableException $parms.EnvironmentId = $EnvironmentId $resCertDetails = Get-LcsEnvironmentRsatCertificate @parms if (Test-PSFFunctionInterrupt) { return } if ($FailOnErrorMessage -and $deploymentStatus.ErrorMessage) { $messageString = "The request against LCS succeeded, but the response was an error message for the operation: $($deploymentStatus.ErrorMessage)." $errorMessagePayload = "`r`n$($deploymentStatus | ConvertTo-Json)" Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus } $outFile = Join-Path -Path $OutputPath -ChildPath $resCertDetails.Data.Filename Set-Content -Path $outFile -Value $([System.Convert]::FromBase64String($resCertDetails.Data.CertificateZipEncoded)) -Encoding Byte $outExtract = Join-Path -Path $OutputPath -ChildPath $([System.IO.Path]::GetFileNameWithoutExtension($outFile)) Expand-Archive -Path $outFile -DestinationPath $outExtract -Force Invoke-TimeSignal -End [PSCustomObject][ordered]@{ Path = $outExtract CerFile = Get-Item -Path "$outExtract\*.cer" | Select-Object -First 1 -ExpandProperty FullName PfxFile = Get-Item -Path "$outExtract\*.pfx" | Select-Object -First 1 -ExpandProperty FullName FileName = $resCertDetails.Data.Filename Password = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($resCertDetails.Data.CertificateSecretEncoded)) } } } ================================================ FILE: d365fo.tools/functions/get-d365lcssharedassetfile.ps1 ================================================  <# .SYNOPSIS Get information for assets from the shared asset library of LCS .DESCRIPTION Get the information for the file assets from the shared asset library of LCS matching the search criteria .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig Although the assets are stored in the shared asset library, their information is retrieved in context of a project to get the full information. .PARAMETER FileType Type of file you want to list from the LCS Asset Library Valid options: "Model" "Process Data Package" "Software Deployable Package" "GER Configuration" "Data Package" "PowerBI Report Model" "E-Commerce Package" "NuGet Package" "Retail Self-Service Package" "Commerce Cloud Scale Unit Extension" Default value is "Software Deployable Package" .PARAMETER AssetName Name of the asset that you are looking for Accepts wildcards for searching. E.g. -AssetName "*ISV*" Default value is "*" which will search for all assets via the Name property .PARAMETER AssetVersion Version of the Asset file that you are looking for It does a simple compare against the response from LCS and only lists the ones that matches Accepts wildcards for searching. E.g. -AssetVersion "*ISV*" Default value is "*" which will search for all files .PARAMETER AssetFilename Name of the file that you are looking for Accepts wildcards for searching. E.g. -AssetFilename "*ISV*" Default value is "*" which will search for all files via the FileName property .PARAMETER AssetDescription Name of the file that you are looking for Accepts wildcards for searching. E.g. -AssetDescription "*ISV*" Default value is "*" which will search for all files via the FileDescription property .PARAMETER AssetId Id of the file that you are looking for Accepts wildcards for searching. E.g. -AssetId "*ISV*" Default value is "*" which will search for all files via the AssetId property .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER Latest Instruct the cmdlet to only fetch the latest file from the Asset Library from LCS .PARAMETER SkipSasGeneration Instruct the cmdlet to only fetch the meta data from the asset file (entry) This is to speed up the listing of entries, in some of the larger areas in the Shared Asset Library .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts Usually this parameter is not used directly, but via the Enable-D365Exception cmdlet See https://github.com/d365collaborative/d365fo.tools/wiki/Exception-handling#what-does-the--enableexception-parameter-do for further information .EXAMPLE PS C:\> Get-D365LcsSharedAssetFile -ProjectId 123456789 -FileType SoftwareDeployablePackage -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will list all Software Deployable Packages in the shared asset library. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .EXAMPLE PS C:\> Get-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage This will list all Software Deployable Packages in the shared asset library. It will search for SoftwareDeployablePackage by using the FileType parameter. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetFilename "*MAIN*" 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. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetFilename "*MAIN*" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetName "*MAIN*" This will list all Software Deployable Packages in the shared asset library that match the "*MAIN*" search pattern in the name of the asset. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetName "*MAIN*" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetDescription "*TEST*" This will list all Software Deployable Packages in the shared asset library that match the "*TEST*" search pattern in the asset description. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetDescription "*TEST*" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetId "500dd860-eacf-4e04-9f18-f9c8fe1d8e03" 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. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetId "500dd860-eacf-4e04-9f18-f9c8fe1d8e03" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> $asset = Get-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage -Latest PS C:\> Invoke-D365AzCopyTransfer -SourceUri $asset.FileLocation -DestinationUri C:\Temp\d365fo.tools\$($asset.Filename) -ShowOriginalProgress This will download the latest Software Deployable Package from the shared asset library in LCS onto your local machine. It will list Software Deployable Packages based on the FileType parameter. It will list the latest (newest) Software Deployable Package. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage -RetryTimeout "00:01:00" 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. It will search for SoftwareDeployablePackage by using the FileType parameter. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Get-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage -SkipSasGeneration This will list all Software Deployable Packages in the shared asset library, but skip the SAS / Download generation It will search for SoftwareDeployablePackage by using the FileType parameter. This will increase the speed getting the list of assets - but you will not get a downloadable link. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .LINK Get-D365LcsApiConfig .LINK Get-D365LcsApiToken .LINK Invoke-D365LcsApiRefreshToken .LINK Set-D365LcsApiConfig .LINK Get-D365LcsAssetFile .NOTES Author: Florian Hopfner (@FH-Inway) #> function Get-D365LcsSharedAssetFile { [CmdletBinding()] [OutputType()] param ( [int] $ProjectId = $Script:LcsApiProjectId, [LcsAssetFileType] $FileType = [LcsAssetFileType]::SoftwareDeployablePackage, [string] $AssetName = "*", [string] $AssetVersion = "*", [string] $AssetFilename = "*", [string] $AssetDescription = "*", [string] $AssetId = "*", [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [Alias('GetLatest')] [switch] $Latest, [switch] $SkipSasGeneration, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) Invoke-TimeSignal -Start if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } $colTemp = Get-LcsSharedAssetFile -BearerToken $BearerToken -LcsApiUri $LcsApiUri -FileType $([int]$FileType) -RetryTimeout $RetryTimeout $assets = $colTemp | Select-PSFObject -TypeName "D365FO.TOOLS.Lcs.Asset.File" -Property "*", "Id as AssetId", ` @{Name = "ProductVersion"; Expression = { [System.Version]$($_.Name.Split(" ") | Select-Object -Last 1 ) } }, ` @{Name = "ProductBuild"; Expression = { [System.Version]$($_.FileName.Split("_") | Select-Object -First 1 -Skip 1) } } if (Test-PSFFunctionInterrupt) { return } if ($Latest) { $latestSharedAsset = $assets | Sort-Object -Property "ModifiedDate" -Descending | Select-Object -First 1 if ($SkipSasGeneration -eq $false) { $latestSharedAsset = Get-LcsFileAsset -BearerToken $BearerToken -ProjectId $ProjectId -LcsApiUri $LcsApiUri -AssetId $latestSharedAsset.Id -RetryTimeout $RetryTimeout $latestSharedAsset | Select-PSFObject -TypeName "D365FO.TOOLS.Lcs.Asset.File" -Property "*", "Id as AssetId", ` @{Name = "ProductVersion"; Expression = { [System.Version]$($_.Name.Split(" ") | Select-Object -Last 1 ) } }, ` @{Name = "ProductBuild"; Expression = { [System.Version]$($_.FileName.Split("_") | Select-Object -First 1 -Skip 1) } } } else { $latestSharedAsset } } else { foreach ($obj in $assets) { if ($obj.Name -NotLike $AssetName) { continue } if ($obj.Version -NotLike $AssetVersion) { continue } if ($obj.FileName -NotLike $AssetFilename) { continue } if ($obj.FileDescription -NotLike $AssetDescription) { continue } if ($obj.Id -NotLike $AssetId) { continue } if ($SkipSasGeneration -eq $false) { $obj = Get-LcsFileAsset -BearerToken $BearerToken -ProjectId $ProjectId -LcsApiUri $LcsApiUri -AssetId $obj.Id -RetryTimeout $RetryTimeout $obj | Select-PSFObject -TypeName "D365FO.TOOLS.Lcs.Asset.File" -Property "*", "Id as AssetId", ` @{Name = "ProductVersion"; Expression = { [System.Version]$($_.Name.Split(" ") | Select-Object -Last 1 ) } }, ` @{Name = "ProductBuild"; Expression = { [System.Version]$($_.FileName.Split("_") | Select-Object -First 1 -Skip 1) } } } else { $obj } } } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/get-d365maintenancemode.ps1 ================================================  <# .SYNOPSIS Get the maintenance mode status of the environment .DESCRIPTION Get the maintenance mode status of the Dynamics 365 environment to make sure that things are in the correct state .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .EXAMPLE PS C:\> Get-D365MaintenanceMode This will get the current state of the maintenance mode of the environment .NOTES Tags: MaintenanceMode, Maintenance, License, Configuration, Servicing Author: Mötz Jensen (@splaxi) .LINK Enable-D365MaintenanceMode .LINK Disable-D365MaintenanceMode #> function Get-D365MaintenanceMode { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 3 )] [string] $DatabaseServer = $Script:DatabaseServer, [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 4 )] [string] $DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 5 )] [string] $SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 6 )] [string] $SqlPwd = $Script:DatabaseUserPassword ) Write-PSFMessage -Level Verbose -Message "Getting Maintenance Mode using SQL scripts." $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $sqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\get-maintenancemode.sql") -join [Environment]::NewLine try { $sqlCommand.Connection.Open() $reader = $sqlCommand.ExecuteReader() while ($reader.Read() -eq $true) { [PSCustomObject]@{ MaintenanceModeEnabled = [bool][int]"$($reader.GetString($($reader.GetOrdinal("VALUE"))))" } } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { $reader.close() if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } } ================================================ FILE: d365fo.tools/functions/get-d365model.ps1 ================================================  <# .SYNOPSIS Get available model from Dynamics 365 Finance & Operations environment .DESCRIPTION Get available model from the machine running the AOS service for Dynamics 365 Finance & Operations .PARAMETER Name Name of the model that you are looking for Accepts wildcards for searching. E.g. -Name "Application*Adaptor" Default value is "*" which will search for all models .PARAMETER Module Name of the module that you want to list models from Accepts wildcards for searchinf. E.g. -Module "Application*Adaptor" Default value is "*" which will search across all modules .PARAMETER CustomizableOnly Instructs the cmdlet to filter out all models that cannot be customized .PARAMETER ExcludeMicrosoftModels Instructs the cmdlet to exclude all models that has Microsoft as the publisher from the output .PARAMETER ExcludeBinaryModels Instruct the cmdlet to exclude binary models from the output .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin Default value is fetched from the current configuration on the machine .PARAMETER PackageDirectory Path to the directory containing the installed package / module Default path is the same as the AOS service "PackagesLocalDirectory" directory Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Get-D365Model Shows the entire list of installed models located in the default location on the machine. A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- AccountsPayableMobile AccountsPayableMobile False DoNotAllow 895571380 Microsoft Corporation ApplicationCommon ApplicationCommon False DoNotAllow 8956718 Microsoft ApplicationFoundation ApplicationFoundation False Allow 450 Microsoft Corporation IsvFoundation IsvFoundation True Allow 895972027 Isv Corp IsvLicense IsvLicense True DoNotAllow 895972028 Isv Corp .EXAMPLE PS C:\> Get-D365Model -CustomizableOnly Shows only the models that are marked as customizable. Will only include models that is Customization = "Allow". A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- ApplicationFoundation ApplicationFoundation False Allow 450 Microsoft Corporation ApplicationPlatform ApplicationPlatform False Allow 400 Microsoft Corporation ApplicationPlatformFormAdaptor ApplicationPlatformFormAdaptor False Allow 855030 Microsoft Corporation IsvFoundation IsvFoundation True Allow 895972027 Isv Corp .EXAMPLE PS C:\> Get-D365Model -ExcludeMicrosoftModels Shows only the models that doesn't have "Microsoft" in the publisher. Will only include models that is Publisher -NotLike "Microsoft*". A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- IsvFoundation IsvFoundation True Allow 895972027 Isv Corp IsvLicense IsvLicense True DoNotAllow 895972028 Isv Corp .EXAMPLE PS C:\> Get-D365Model -ExcludeBinaryModels Shows only the models that are NOT binary. Will only include models that is IsBinary = "False". A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- AccountsPayableMobile AccountsPayableMobile False DoNotAllow 895571380 Microsoft Corporation ApplicationCommon ApplicationCommon False DoNotAllow 8956718 Microsoft ApplicationFoundation ApplicationFoundation False Allow 450 Microsoft Corporation .EXAMPLE PS C:\> Get-D365Model -CustomizableOnly -ExcludeMicrosoftModels Shows only the models that are marked as customizable and NOT from Microsoft. Will only include models that is Customization = "Allow". Will only include models that is Publisher -NotLike "Microsoft*". A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- IsvFoundation IsvFoundation True Allow 895972027 Isv Corp .EXAMPLE PS C:\> Get-D365Model -Name "Application*Adaptor" Shows the list of models where the name fits the search "Application*Adaptor". A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- ApplicationFoundationFormAd... ApplicationFoundationFormAd... False DoNotAllow 855029 Microsoft Corporation ApplicationPlatformFormAdaptor ApplicationPlatformFormAdaptor False Allow 855030 Microsoft Corporation ApplicationSuiteFormAdaptor ApplicationSuiteFormAdaptor False DoNotAllow 855028 Microsoft Corporation ApplicationWorkspacesFormAd... ApplicationWorkspacesFormAd... False DoNotAllow 855066 Microsoft Corporation .EXAMPLE PS C:\> Get-D365Model -Module ApplicationSuite Shows only the models that are inside the ApplicationSuite module. A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- Electronic Reporting Applic... ApplicationSuite False DoNotAllow 855009 Microsoft Corporation Foundation ApplicationSuite False DoNotAllow 17 Microsoft Corporation SCMControls ApplicationSuite False DoNotAllow 855891 Microsoft Corporation Tax Books Application Suite... ApplicationSuite False DoNotAllow 895570102 Microsoft Corporation Tax Engine Application Suit... ApplicationSuite False DoNotAllow 8957001 Microsoft Corporation .EXAMPLE PS C:\> Get-D365Model -Name "*Application*" -Module "*Suite*" Shows the list of models where the name fits the search "*Application*" and the module name fits the search "*Suite*". A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- ApplicationSuiteFormAdaptor ApplicationSuiteFormAdaptor False DoNotAllow 855028 Microsoft Corporation AtlApplicationSuite AtlApplicationSuite False DoNotAllow 895972466 Microsoft Corporation Electronic Reporting Applic... ApplicationSuite False DoNotAllow 855009 Microsoft Corporation Tax Books Application Suite... ApplicationSuite False DoNotAllow 895570102 Microsoft Corporation Tax Engine Application Suit... ApplicationSuite False DoNotAllow 8957001 Microsoft Corporation .NOTES Tags: PackagesLocalDirectory, Servicing, Model, Models, Module, Modules Author: Mötz Jensen (@Splaxi) Author: Martin Dráb (@goshoom) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. #> function Get-D365Model { [CmdletBinding()] param ( [string] $Name = "*", [Parameter(ValueFromPipelineByPropertyName = $true)] [Alias("ModuleName")] [string] $Module = "*", [switch] $CustomizableOnly, [switch] $ExcludeMicrosoftModels, [switch] $ExcludeBinaryModels, [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) begin { [System.Collections.ArrayList] $Files2Process = New-Object -TypeName "System.Collections.ArrayList" $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Management.Delta.dll")) $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Management.Diff.dll")) $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Management.Merge.dll")) $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Management.Core.dll")) $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.dll")) $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Core.dll")) $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Storage.dll")) $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll")) Import-AssemblyFileIntoMemory -Path $($Files2Process.ToArray()) Write-PSFMessage -Level Verbose -Message "Intializing RuntimeProvider." $runtimeProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.Runtime.RuntimeProviderConfiguration -ArgumentList $PackageDirectory $metadataProviderFactoryViaRuntime = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProviderViaRuntime = $metadataProviderFactoryViaRuntime.CreateRuntimeProvider($runtimeProviderConfiguration) Write-PSFMessage -Level Verbose -Message "MetadataProvider initialized." -Target $metadataProviderViaRuntime $models = $metadataProviderViaRuntime.ModelManifest.ListModelInfos() $models | ForEach-Object { $_ | Add-Member -MemberType NoteProperty -Name 'IsBinary' -Value $false } Write-PSFMessage -Level Verbose -Message "Testing if the cmdlet is running on a OneBox or not." -Target $Script:IsOnebox if ($Script:IsOnebox) { Write-PSFMessage -Level Verbose -Message "Machine is onebox. Initializing DiskProvider too." $diskProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $diskProviderConfiguration.AddMetadataPath($PackageDirectory) $metadataProviderFactoryViaDisk = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProviderViaDisk = $metadataProviderFactoryViaDisk.CreateDiskProvider($diskProviderConfiguration) Write-PSFMessage -Level Verbose -Message "MetadataProvider initialized." -Target $metadataProviderViaDisk $diskModels = $metadataProviderViaDisk.ModelManifest.ListModelInfos() foreach ($model in $models) { if ($diskModels.Name -NotContains $model.Name) { $model.IsBinary = $true } } $uncompiledModels = @( foreach ($model in $diskModels) { if ($models.Name -NotContains $model.Name) { $model | Add-Member -MemberType NoteProperty -Name 'IsBinary' -Value $false $model } } ) # Combined both arrays $models = $models + $uncompiledModels } if ($CustomizableOnly) { $models = $models | Where-Object Customization -eq "Allow" } if ($ExcludeBinaryModels -eq $true) { $models = $models | Where-Object IsBinary -eq $false } } process { if (Test-PSFFunctionInterrupt) { return } $modelsLocal = $models $modelsLocal = $modelsLocal | Where-Object Module -like $Module Write-PSFMessage -Level Verbose -Message "Looping through all models." foreach ($obj in $($modelsLocal | Sort-Object Name, Module)) { Write-PSFMessage -Level Verbose -Message "Filtering out all models that doesn't match the model search." -Target $obj if ($obj.Name -NotLike $Name) { continue } if ($ExcludeMicrosoftModels -and $obj.Publisher -like "Microsoft*") { continue } $obj | Select-PSFObject "Name as ModelName", * -ExcludeProperty Name -TypeName "D365FO.TOOLS.ModelInfo" } } } ================================================ FILE: d365fo.tools/functions/get-d365module.ps1 ================================================  <# .SYNOPSIS Get installed package / module from Dynamics 365 Finance & Operations environment .DESCRIPTION Get installed package / module from the machine running the AOS service for Dynamics 365 Finance & Operations .PARAMETER Name Name of the package / module that you are looking for Accepts wildcards for searching. E.g. -Name "Application*Adaptor" Default value is "*" which will search for all packages / modules .PARAMETER ExcludeBinaryModules Instruct the cmdlet to exclude binary modules from the output .PARAMETER InDependencyOrder Instructs the cmdlet to return modules in dependency order, starting with modules with no references to other modules. .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin Default value is fetched from the current configuration on the machine .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Get-D365Module Shows the entire list of installed packages / modules located in the default location on the machine. A result set example: ModuleName IsBinary Version References ---------- -------- ------- ---------- AccountsPayableMobile False 10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli... ApplicationCommon False 10.0.8008.26462 {ApplicationFoundation, ApplicationPlatform} ApplicationFoundation False 7.0.5493.35504 {ApplicationPlatform} ApplicationFoundationFormAdaptor False 7.0.4841.35227 {ApplicationPlatform, ApplicationFoundation, TestE... Custom True 10.0.0.0 {ApplicationPlatform} .EXAMPLE PS C:\> Get-D365Module -ExcludeBinaryModules Outputs the all packages / modules that are NOT binary. Will only include modules that is IsBinary = "False". A result set example: ModuleName IsBinary Version References ---------- -------- ------- ---------- AccountsPayableMobile False 10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli... ApplicationCommon False 10.0.8008.26462 {ApplicationFoundation, ApplicationPlatform} ApplicationFoundation False 7.0.5493.35504 {ApplicationPlatform} ApplicationFoundationFormAdaptor False 7.0.4841.35227 {ApplicationPlatform, ApplicationFoundation, TestE... .EXAMPLE PS C:\> Get-D365Module -InDependencyOrder Return packages / modules in dependency order, starting with modules with no references to other modules. A result set example: ModuleName IsBinary Version References ---------- -------- ------- ---------- ApplicationPlatform False 7.0.0.0 {} ApplicationFoundation False 7.0.0.0 {ApplicationPlatform} ApplicationCommon False 10.21.36.8818 {ApplicationFoundation, ApplicationPlatform} AppTroubleshootingCore False 10.21.1136.2... {ApplicationCommon, ApplicationFoundation, Applica... .EXAMPLE PS C:\> Get-D365Module -Name "Application*Adaptor" Shows the list of installed packages / modules where the name fits the search "Application*Adaptor". A result set example: ModuleName IsBinary Version References ---------- -------- ------- ---------- ApplicationFoundationFormAdaptor False 7.0.4841.35227 {ApplicationPlatform, ApplicationFoundation, TestE... ApplicationPlatformFormAdaptor False 7.0.4841.35227 {ApplicationPlatform, TestEssentials} ApplicationSuiteFormAdaptor False 10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli... ApplicationWorkspacesFormAdaptor False 10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli... .NOTES Tags: PackagesLocalDirectory, Servicing, Model, Models, Package, Packages Author: Mötz Jensen (@Splaxi) Author: Martin Dráb (@goshoom) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. #> function Get-D365Module { [CmdletBinding()] param ( [string] $Name = "*", [switch] $ExcludeBinaryModules, [Alias("Dependency")] [switch] $InDependencyOrder, [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) begin { [System.Collections.ArrayList] $Files2Process = New-Object -TypeName "System.Collections.ArrayList" $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Management.Delta.dll")) $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Management.Diff.dll")) $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Management.Merge.dll")) $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Management.Core.dll")) $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.dll")) $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Core.dll")) $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Storage.dll")) $null = $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll")) Import-AssemblyFileIntoMemory -Path $($Files2Process.ToArray()) } process { if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Intializing RuntimeProvider." $runtimeProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.Runtime.RuntimeProviderConfiguration -ArgumentList $PackageDirectory $metadataProviderFactoryViaRuntime = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProviderViaRuntime = $metadataProviderFactoryViaRuntime.CreateRuntimeProvider($runtimeProviderConfiguration) Write-PSFMessage -Level Verbose -Message "MetadataProvider initialized." -Target $metadataProviderViaRuntime try { $modules = $metadataProviderViaRuntime.ModelManifest.ListModulesInDependencyOrder() } catch { Write-PSFMessage -Level Warning -Message "Failed to retrieve runtime modules in dependency order. Falling back to ListModules()." -Target $metadataProviderViaRuntime $modules = $metadataProviderViaRuntime.ModelManifest.ListModules() } $modules | ForEach-Object { $_ | Add-Member -MemberType NoteProperty -Name 'IsBinary' -Value $false } Write-PSFMessage -Level Verbose -Message "Testing if the cmdlet is running on a OneBox or not." -Target $Script:IsOnebox if ($Script:IsOnebox) { Write-PSFMessage -Level Verbose -Message "Machine is onebox. Initializing DiskProvider too." $diskProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $diskProviderConfiguration.AddMetadataPath($PackageDirectory) $metadataProviderFactoryViaDisk = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProviderViaDisk = $metadataProviderFactoryViaDisk.CreateDiskProvider($diskProviderConfiguration, $metadataProviderViaRuntime.ModelManifest) Write-PSFMessage -Level Verbose -Message "MetadataProvider initialized." -Target $metadataProviderViaDisk try { $diskModules = $metadataProviderViaDisk.ModelManifest.ListModulesInDependencyOrder() } catch { Write-PSFMessage -Level Warning -Message "Failed to retrieve disk modules in dependency order. Falling back to ListModules()." -Target $metadataProviderViaDisk $diskModules = $metadataProviderViaDisk.ModelManifest.ListModules() } foreach ($module in $modules) { if ($diskModules.Name -NotContains $module.Name) { $module.IsBinary = $true } } $uncompiledModules = @( foreach ($module in $diskModules) { if ($modules.Name -NotContains $module.Name) { $module | Add-Member -MemberType NoteProperty -Name 'IsBinary' -Value $false $module } } ) # Combined both arrays $modules = $modules + $uncompiledModules } if ($ExcludeBinaryModules -eq $true) { $modules = $modules | Where-Object IsBinary -eq $false } if ($InDependencyOrder -eq $false) { $modules = $modules | Sort-Object Name } Write-PSFMessage -Level Verbose -Message "Looping through all modules." foreach ($obj in $modules) { Write-PSFMessage -Level Verbose -Message "Filtering out all modules that doesn't match the model search." -Target $obj if ($obj.Name -NotLike $Name) { continue } $moduleName = $obj.Name $res = [Ordered]@{ Module = $moduleName ModuleName = $moduleName IsBinary = $obj.IsBinary PSTypeName = 'D365FO.TOOLS.ModuleInfo' } $moduleAssemblyPath = Join-Path $PackageDirectory "$moduleName\bin\Dynamics.AX.$moduleName.dll" if (Test-Path -Path $moduleAssemblyPath) { $fileVersion = Get-FileVersion -Path $moduleAssemblyPath $version = $fileVersion.FileVersion $versionUpdated = $fileVersion.FileVersionUpdated } else { $version = "" $versionUpdated = "" } $res.Version = $version $res.VersionUpdated = $versionUpdated $res.References = $obj.References [PSCustomObject]$res } } } ================================================ FILE: d365fo.tools/functions/get-d365offlineauthenticationadminemail.ps1 ================================================  <# .SYNOPSIS Gets the registered offline administrator e-mail configured .DESCRIPTION Get the registered offline administrator from the "DynamicsDevConfig.xml" file located in the default Package Directory .EXAMPLE PS C:\> Get-D365OfflineAuthenticationAdminEmail Will read the DynamicsDevConfig.xml and display the registered Offline Administrator E-mail address. .NOTES Tags: Development, Email, DynamicsDevConfig, Offline, Authentication This cmdlet is inspired by the work of "Sheikh Sohail Hussain" (twitter: @SSohailHussain) His blog can be found here: http://d365technext.blogspot.com The specific blog post that we based this cmdlet on can be found here: http://d365technext.blogspot.com/2018/07/offline-authentication-admin-email.html #> function Get-D365OfflineAuthenticationAdminEmail { [CmdletBinding()] param () $filePath = Join-Path (Join-Path $Script:PackageDirectory "bin") "DynamicsDevConfig.xml" if(-not (Test-PathExists -Path $filePath -Type Leaf)) {return} $namespace = @{ns="http://schemas.microsoft.com/dynamics/2012/03/development/configuration"} $OfflineAuthAdminEmail = Select-Xml -XPath "/ns:DynamicsDevConfig/ns:OfflineAuthenticationAdminEmail" -Path $filePath -Namespace $namespace $AdminEmail = $OfflineAuthAdminEmail.Node.InnerText [PSCustomObject] @{Email = $AdminEmail} } ================================================ FILE: d365fo.tools/functions/get-d365packagebundledetail.ps1 ================================================  <# .SYNOPSIS Get the details from an axscdppkg file .DESCRIPTION Get the details from an axscdppkg file by extracting it like a zip file. Capable of extracting the manifest details from the inner packages as well .PARAMETER Path Path to the axscdppkg file you want to analyze .PARAMETER ExtractionPath Path where you want the cmdlet to work with extraction of all the files Default value is: C:\Users\Username\AppData\Local\Temp .PARAMETER KB KB number of the hotfix that you are looking for Accepts wildcards for searching. E.g. -KB "4045*" Default value is "*" which will search for all KB's .PARAMETER Hotfix Package Id / Hotfix number the hotfix that you are looking for Accepts wildcards for searching. E.g. -Hotfix "7045*" Default value is "*" which will search for all hotfixes .PARAMETER Traverse Switch to instruct the cmdlet to traverse the inner packages and extract their details .PARAMETER KeepFiles Switch to instruct the cmdlet to keep the files for further manual analyze .PARAMETER IncludeRawManifest Switch to instruct the cmdlet to include the raw content of the manifest file Only works with the -Traverse option .EXAMPLE PS C:\> Get-D365PackageBundleDetail -Path "c:\temp\HotfixPackageBundle.axscdppkg" -Traverse 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. .EXAMPLE PS C:\> Get-D365PackageBundleDetail -Path "c:\temp\HotfixPackageBundle.axscdppkg" -ExtractionPath C:\Temp\20180905 -Traverse -KeepFiles 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. .EXAMPLE PS C:\> Get-D365PackageBundleDetail -Path C:\temp\HotfixPackageBundle.axscdppkg -Traverse -IncludeRawManifest This is an advanced scenario. This will traverse the "HotfixPackageBundle.axscdppkg" file and will include the raw manifest file details in the output. .EXAMPLE PS C:\> Get-D365PackageBundleDetail -Path C:\temp\HotfixPackageBundle.axscdppkg -Traverse -IncludeRawManifest | ForEach-Object {$_.RawManifest | Out-File "C:\temp\$($_.PackageId).txt"} This is an advanced scenario. This will traverse the "HotfixPackageBundle.axscdppkg" file and save the manifest files into c:\temp. Everything else is omitted and cleaned up. .NOTES Tags: Hotfix, KB, Manifest, HotfixPackageBundle, axscdppkg, Package, Bundle, Deployable Author: Mötz Jensen (@Splaxi) #> function Get-D365PackageBundleDetail { [CmdletBinding()] param ( [Parameter(Mandatory = $True)] [Alias('File')] [string] $Path, [string] $ExtractionPath = ([System.IO.Path]::GetTempPath()), [string] $KB = "*", [string] $Hotfix = "*", [switch] $Traverse, [switch] $KeepFiles, [switch] $IncludeRawManifest ) begin { Invoke-TimeSignal -Start if (!(Test-Path -Path $Path -PathType Leaf)) { Write-PSFMessage -Level Host -Message "The $Path file wasn't found. Please ensure the file exists and you have enough permission/c> to access the file." Stop-PSFFunction -Message "Stopping because a file is missing." return } Unblock-File -Path $Path if(!(Test-Path -Path $ExtractionPath)) { Write-PSFMessage -Level Verbose -Message "The extract path didn't exists. Creating it." -Target $ExtractionPath $null = New-Item -Path $ExtractionPath -Force -ItemType Directory } if ($Path -notlike "*.zip") { $tempPathZip = Join-Path $ExtractionPath "$($(New-Guid).ToString()).zip" Write-PSFMessage -Level Verbose -Message "The file isn't a zip file. Copying the file to $tempPathZip" -Target $tempPathZip Copy-Item -Path $Path -Destination $tempPathZip -Force $Path = $tempPathZip } $packageTemp = Join-Path $ExtractionPath ((Get-Random -Maximum 99999).ToString()) $oldprogressPreference = $global:progressPreference $global:progressPreference = 'silentlyContinue' } process { if (Test-PSFFunctionInterrupt) {return} Write-PSFMessage -Level Verbose -Message "Extracting the zip file to $packageTemp" -Target $packageTemp Expand-Archive -Path $Path -DestinationPath $packageTemp if ($Traverse) { $files = Get-ChildItem -Path $packageTemp -Filter "*.axscdp" foreach ($item in $files) { $filename = [System.IO.Path]::GetFileNameWithoutExtension($item.Name) $tempFile = Join-Path $packageTemp "$filename.zip" Write-PSFMessage -Level Verbose -Message "Coping $($item.FullName) to $tempFile" -Target $tempFile Copy-Item -Path $item.FullName -Destination $tempFile $tempDir = (Join-Path $packageTemp ($filename.Replace("DynamicsAX_", ""))) $null = New-Item -Path $tempDir -ItemType Directory -Force Write-PSFMessage -Level Verbose -Message "Extracting the zip file $tempFile to $tempDir" -Target $tempDir Expand-Archive -Path $tempFile -DestinationPath $tempDir } $manifestFiles = Get-ChildItem -Path $packageTemp -Recurse -Filter "PackageManifest.xml" $namespace = @{ns = "http://schemas.datacontract.org/2004/07/Microsoft.Dynamics.AX.Servicing.SCDP.Packaging"; nsKB = "http://schemas.microsoft.com/2003/10/Serialization/Arrays"} Write-PSFMessage -Level Verbose -Message "Getting all the information from the manifest file" foreach ($item in $manifestFiles) { $raw = (Get-Content -Path $item.FullName) -join [Environment]::NewLine $xmlDoc = [xml]$raw $kbs = Select-Xml -Xml $xmlDoc -XPath "//ns:UpdatePackageManifest/ns:KBNumbers/nsKB:string" -Namespace $namespace $packageId = Select-Xml -Xml $xmlDoc -XPath "//ns:UpdatePackageManifest/ns:PackageId/ns:PackageId" -Namespace $namespace $strPackage = $packageId.Node.InnerText $arrKbs = $kbs.node.InnerText if($packageId.Node.InnerText -notlike $Hotfix) {continue} if(@($arrKbs) -notlike $KB) {continue} #* Search across an array with like $Obj = [PSCustomObject]@{Hotfix = $strPackage KBs = ($arrKbs -Join ";")} if($IncludeRawManifest) {$Obj.RawManifest = $raw} $Obj | Select-PSFObject -TypeName "D365FO.TOOLS.PackageBundleManifestDetail" } } else { Get-ChildItem -Path $packageTemp -Filter "*.*" | Select-PSFObject -TypeName "D365FO.TOOLS.PackageBundleDetail" "BaseName as Name" } } end { if(!$Keepfiles) { Remove-Item -Path $packageTemp -Recurse -Force -ErrorAction SilentlyContinue if(![system.string]::IsNullOrEmpty($tempPathZip)) { Remove-Item -Path $tempPathZip -Recurse -Force -ErrorAction SilentlyContinue } } $global:progressPreference = $oldprogressPreference Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/get-d365packagelabelresourcefile.ps1 ================================================  <# .SYNOPSIS Get label / resource file from a package .DESCRIPTION Get label (resource) file from the package directory of a Dynamics 365 Finance & Operations environment .PARAMETER PackageDirectory Path to the directory containing the installed packages Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .PARAMETER Name Name of the label (resource) file you are looking for Accepts wildcards for searching. E.g. -Name "Fixed*Accounting" Default value is "*" which will search for all label files .PARAMETER Language The language of the label file you are looking for Accepts wildcards for searching. E.g. -Language "en*" Default value is "en-US" which will search for en-US language files .EXAMPLE PS C:\> Get-D365PackageLabelResourceFile -PackageDirectory "C:\AOSService\PackagesLocalDirectory\ApplicationSuite" Shows all the label files for ApplicationSuite package .EXAMPLE PS C:\> Get-D365PackageLabelResourceFile -PackageDirectory "C:\AOSService\PackagesLocalDirectory\ApplicationSuite" -Name "Fixed*Accounting" Shows the label files for ApplicationSuite package where the name fits the search "Fixed*Accounting" .EXAMPLE PS C:\> Get-D365InstalledPackage -Name "ApplicationSuite" | Get-D365PackageLabelResourceFile Shows all label files (en-US) for the ApplicationSuite package .NOTES Tags: PackagesLocalDirectory, Label, Labels, Language, Development, Servicing, Module, Package, Packages Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. #> function Get-D365PackageLabelResourceFile { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true)] [Parameter(Mandatory = $true, ParameterSetName = 'Specific')] [Alias('Path')] [string] $PackageDirectory, [string] $Name = "*", [string] $Language = "en-US" ) BEGIN {} PROCESS { $Path = $PackageDirectory if (Test-Path "$Path\Resources\$Language") { $files = Get-ChildItem -Path ("$Path\Resources\$Language\*.resources.dll") foreach ($obj in $files) { if ($obj.Name.Replace(".resources.dll", "") -NotLike $Name) { continue } [PSCustomObject]@{ LabelName = ($obj.Name).Replace(".resources.dll", "") LanguageName = (Get-Command $obj.FullName).FileVersionInfo.Language Language = $obj.directory.basename FilePath = $obj.FullName } } } else { Write-PSFMessage -Level Verbose -Message "Skipping `"$("$Path\Resources\$Language")`" because it doesn't exist." } } END {} } ================================================ FILE: d365fo.tools/functions/get-d365packagelabelresources.ps1 ================================================  <# .SYNOPSIS Get label from the resource file .DESCRIPTION Get label details from the resource file for a Dynamics 365 Finance & Operations environment .PARAMETER FilePath The path to resource file that you want to get label details from .PARAMETER Name Name of the label you are looking for Accepts wildcards for searching. E.g. -Name "@PRO*" Default value is "*" which will search for all labels in the resource file .PARAMETER Value Value of the label you are looking for Accepts wildcards for searching. E.g. -Name "*Qty*" Default value is "*" which will search for all values in the resource file .PARAMETER IncludePath Switch to indicate whether you want the result set to include the path to the resource file or not Default is OFF - path details will not be part of the output .EXAMPLE PS C:\> Get-D365PackageLabelResources -Path "C:\AOSService\PackagesLocalDirectory\ApplicationSuite\Resources\en-US\PRO.resources.dll" Will get all labels from the "PRO.resouce.dll" file The language is determined by the path to the resource file and nothing else .EXAMPLE PS C:\> Get-D365PackageLabelResources -Path "C:\AOSService\PackagesLocalDirectory\ApplicationSuite\Resources\en-US\PRO.resources.dll" -Name "@PRO505" Will get the label with the name "@PRO505" from the "PRO.resouce.dll" file The language is determined by the path to the resource file and nothing else .EXAMPLE PS C:\> Get-D365PackageLabelResources -Path "C:\AOSService\PackagesLocalDirectory\ApplicationSuite\Resources\en-US\PRO.resources.dll" -Value "*qty*" Will get all the labels where the value fits the search "*qty*" from the "PRO.resouce.dll" file The language is determined by the path to the resource file and nothing else .EXAMPLE PS C:\> Get-D365InstalledPackage -Name "ApplicationSuite" | Get-D365PackageLabelResourceFile -Language "da" | Get-D365PackageLabelResources -value "*batch*" -IncludePath 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*". The path to the label file is included in the output. .NOTES Tags: PackagesLocalDirectory, Label, Labels, Language, Development, Servicing, Resource, Resources Author: Mötz Jensen (@Splaxi) There are several advanced scenarios for this cmdlet. See more on github and the wiki pages. #> function Get-D365PackageLabelResources { [CmdletBinding(DefaultParameterSetName = 'Default')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] param ( [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true)] [Parameter(Mandatory = $true, ParameterSetName = 'Specific')] [Alias('Path')] [string] $FilePath, [string] $Name = "*", [string] $Value = "*", [switch] $IncludePath ) BEGIN {} PROCESS { $assembly = [Reflection.Assembly]::LoadFile($FilePath) $resNames = $assembly.GetManifestResourceNames() $resname = $resNames[0].Replace(".resources", "") $resLanguage = $resname.Split(".")[1] $resMan = New-Object -TypeName System.Resources.ResourceManager -ArgumentList $resname, $assembly $language = New-Object System.Globalization.CultureInfo -ArgumentList "en-US" $resources = $resMan.GetResourceSet($language, $true, $true) foreach ($obj in $resources) { if ($obj.Name -NotLike $Name) { continue } if ($obj.Value -NotLike $Value) { continue } $res = [PSCustomObject]@{ Name = $obj.Name Language = $resLanguage Value = $obj.Value } if ($IncludePath.IsPresent) { $res | Add-Member -MemberType NoteProperty -Name 'Path' -Value $FilePath } $res } } END {} } ================================================ FILE: d365fo.tools/functions/get-d365productinformation.ps1 ================================================  <# .SYNOPSIS Returns information about D365FO .DESCRIPTION Gets detailed information about application and platform .EXAMPLE PS C:\> Get-D365ProductInformation This will get product, platform and application version details for the environment .NOTES Tags: Build, Version, Reference, ProductVersion, ProductDetails, Product Author: Rasmus Andersen (@ITRasmus) The cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations. The call to the dll file gets all relevant product details for the environment. #> function Get-D365ProductInformation { [CmdletBinding()] param () return Get-ProductInfoProvider } ================================================ FILE: d365fo.tools/functions/get-d365rsatcertificatethumbprint.ps1 ================================================  <# .SYNOPSIS Get the thumbprint from the RSAT certificate .DESCRIPTION Locate the thumbprint for the certificate created during the RSAT installation .EXAMPLE PS C:\> Get-D365RsatCertificateThumbprint This will locate any certificates that has 127.0.0.1 in its name. It will show the subject and the thumbprint values. .NOTES Tags: RSAT, Certificate, Testing, Regression Suite Automation Test, Regression, Test, Automation. Author: Mötz Jensen (@Splaxi) #> function Get-D365RsatCertificateThumbprint { [CmdletBinding()] [OutputType()] param ( ) Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object Subject -like "*127.0.0.1*" | Format-Table Thumbprint, Subject, FriendlyName, NotAfter } ================================================ FILE: d365fo.tools/functions/get-d365rsatplaybackfile.ps1 ================================================  <# .SYNOPSIS Get the RSAT playback files .DESCRIPTION Get all the RSAT playback files from the last executions .PARAMETER Path The path where the RSAT tool will be writing the files The default path is: "C:\Users\USERNAME\AppData\Roaming\regressionTool\playback" .PARAMETER Name Name of Test Case that you are looking for Default value is "*" which will search for all Test Cases and their corresponding files .PARAMETER ExecutionUsername Name of the user account has been running the RSAT tests on a machine that isn't the same as the current user 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 .EXAMPLE PS C:\> Get-D365RsatPlaybackFile This will get all the RSAT playback files. It will search for the files in the current user AppData system folder. .EXAMPLE PS C:\> Get-D365RsatPlaybackFile -Name *4080* This will get all the RSAT playback files which has "4080" as part of its name. It will search for the files in the current user AppData system folder. .EXAMPLE PS C:\> Get-D365RsatPlaybackFile -ExecutionUsername RSAT-ServiceAccount This will get all the RSAT playback files that were executed by the RSAT-ServiceAccount user. It will search for the files in the RSAT-ServiceAccount user AppData system folder. .NOTES Tags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, Playback Author: Mötz Jensen (@Splaxi) #> function Get-D365RsatPlaybackFile { [CmdletBinding(DefaultParameterSetName = 'Default')] [OutputType()] param ( [Parameter(Mandatory = $false, ParameterSetName = "Default")] [string] $Path = $Script:RsatplaybackPath, [Parameter(Mandatory = $false)] [string] $Name = "*", [Parameter(Mandatory = $false, ParameterSetName = "ExecutionUser")] [string] $ExecutionUsername ) if ($PSCmdlet.ParameterSetName -eq "ExecutionUser") { $Path = $Path.Replace("$($env:UserName)", $ExecutionUsername) if (-not (Test-PathExists -Path $Path -Type Container)) { return } } Get-ChildItem -Path $Path -Recurse | Where-Object { $_.Name -like $Name } | Select-PSFObject "LastWriteTime as LastRuntime", "Name as Filename", "Fullname as File" } ================================================ FILE: d365fo.tools/functions/get-d365rsatsoaphostname.ps1 ================================================  <# .SYNOPSIS Get the SOAP hostname for the D365FO environment .DESCRIPTION Get the SOAP hostname from the IIS configuration, to be used during the Rsat configuration .EXAMPLE PS C:\> Get-D365RsatSoapHostname This will get the SOAP hostname from IIS. It will display the SOAP URL / URI correctly formatted, to be used during the configuration of Rsat. .NOTES Tags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, SOAP Author: Mötz Jensen (@Splaxi) #> function Get-D365RsatSoapHostname { [CmdletBinding()] [OutputType()] param () [PSCustomObject]@{ SoapHostname = (Get-WebBinding | Where-Object bindingInformation -like *soap*).bindingInformation.Replace("*:443:", "") } } ================================================ FILE: d365fo.tools/functions/get-d365runbook.ps1 ================================================  <# .SYNOPSIS Get a Dynamics 365 Runbook .DESCRIPTION Get the full path and filename of a Dynamics 365 Runbook .PARAMETER Path Path to the folder containing the runbook files The default path is "InstallationRecord" which is normally located on the "C:\DynamicsAX\InstallationRecords" .PARAMETER Name Name of the runbook file that you are looking for The parameter accepts wildcards. E.g. -Name *hotfix-20181024* .PARAMETER Latest Instruct the cmdlet to only get the latest runbook file, based on the last written attribute .EXAMPLE PS C:\> Get-D365Runbook This will list all runbooks that are available in the default location. .EXAMPLE PS C:\> Get-D365Runbook -Latest This will get the latest runbook file from the default InstallationRecords directory on the machine. .EXAMPLE PS C:\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. .EXAMPLE PS C:\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer | Out-File "C:\Temp\d365fo.tools\runbook-analyze-results.xml" This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. The output will be saved into the "C:\Temp\d365fo.tools\runbook-analyze-results.xml" file. .EXAMPLE PS C:\> Get-D365Runbook | Backup-D365Runbook This will save a copy of all runbooks from the default location and save them to "c:\temp\d365fo.tools\runbookbackups" .EXAMPLE PS C:\> notepad.exe (Get-D365Runbook -Latest).File This will find the latest runbook file and open it with notepad. .NOTES Tags: Runbook, Servicing, Hotfix, DeployablePackage, Deployable Package, InstallationRecordsDirectory, Installation Records Directory Author: Mötz Jensen (@Splaxi) #> function Get-D365Runbook { [CmdletBinding()] param ( [Parameter(ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)] [string] $Path = (Join-Path $Script:InstallationRecordsDir "Runbooks"), [string] $Name = "*", [switch] $Latest ) begin { if (-not (Test-PathExists -Path $Path -Type Container -WarningAction $WarningPreference -ErrorAction $ErrorActionPreference)) { return } } process { if (Test-PSFFunctionInterrupt) { return } $files = Get-ChildItem -Path "$Path\*.xml" | Sort-Object -Descending { $_.LastWriteTime } if ($Latest) { $obj = $files | Select-Object -First 1 $obj | Select-PSFObject "Name as Filename", "LastWriteTime as LastModified", "Fullname as File" } else { foreach ($obj in $files) { if ($obj.Name -NotLike $Name) { continue } $obj | Select-PSFObject "Name as Filename", "LastWriteTime as LastModified", "Fullname as File" } } } } ================================================ FILE: d365fo.tools/functions/get-d365runbookid.ps1 ================================================  <# .SYNOPSIS Get runbook id .DESCRIPTION Get the runbook id from inside a runbook file .PARAMETER Path Path to the runbook file that you want to analyse Accepts value from pipeline, also by property .EXAMPLE PS C:\> Get-D365RunbookId -Path "C:\DynamicsAX\InstallationRecords\Runbooks\Runbook.xml" This will inspect the Runbook.xml file and output the runbookid from inside the XML document. .EXAMPLE PS C:\> Get-D365Runbook | Get-D365RunbookId This will find all runbook file(s) and have them analyzed by the Get-D365RunbookId cmdlet to output the runbookid(s). .EXAMPLE PS C:\> Get-D365Runbook -Latest | Get-D365RunbookId This will find the latest runbook file and have it analyzed by the Get-D365RunbookId cmdlet to output the runbookid. .NOTES Tags: Runbook, Analyze, RunbookId, Runbooks Author: Mötz Jensen (@Splaxi) #> function Get-D365RunbookId { [CmdletBinding()] [OutputType()] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)] [Alias('File')] [string] $Path ) process { if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } [xml]$xmlRunbook = Get-Content $Path [PSCustomObject]@{ RunbookId = $xmlRunbook.SelectSingleNode("/RunbookData/RunbookID")."#text" } } } ================================================ FILE: d365fo.tools/functions/get-d365runbooklogfile.ps1 ================================================  <# .SYNOPSIS Get log file from a Runbook step .DESCRIPTION Get the log files for a specific Runbook step .PARAMETER Path Path to Software Deployable Package that was run in connection with the runbook .PARAMETER Step Step id for the step that you want to locate the log files for .PARAMETER Latest Instruct the cmdlet to only work with the latest log file Is based on the last written attribute on the log file .PARAMETER OpenInEditor Instruct the cmdlet to open the log file in the default text editor .EXAMPLE PS C:\> Get-D365RunbookLogFile -Path "C:\Temp\PU35" -Step 34 This will locate all logfiles that has been outputted from the Step 34 from the PU35 installation. The output will list the complete path to the log files. An output example: Filename : AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log LastModified : 8/7/2020 12:40:34 PM File : C:\Temp\PU35\RunbookWorkingFolder\Runbook\MININT-F36S5EH\DIXFService\34\Log\AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log Filename : AutoUpdateDIXFService.ps1-2020-07-8--12-36-22.log LastModified : 8/7/2020 12:36:22 PM File : C:\Temp\PU35\RunbookWorkingFolder\Runbook\MININT-F36S5EH\DIXFService\34\Log\AutoUpdateDIXFService.ps1-2020-07-8--12-36-22.log Filename : AutoUpdateDIXFService.ps1-2020-05-8--19-15-07.log LastModified : 8/5/2020 7:15:07 PM File : C:\Temp\PU35\RunbookWorkingFolder\Runbook\MININT-F36S5EH\DIXFService\34\Log\AutoUpdateDIXFService.ps1-2020-05-8--19-15-07.log .EXAMPLE PS C:\> Get-D365RunbookLogFile -Path "C:\Temp\PU35" -Step 34 -Latest This will locate all logfiles that has been outputted from the Step 34 from the PU35 installation. The output will be limited to the latest log, based on last write time. The output will list the complete path to the log file. An output example: Filename : AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log LastModified : 8/7/2020 12:40:34 PM File : C:\Temp\PU35\RunbookWorkingFolder\Runbook\MININT-F36S5EH\DIXFService\34\Log\AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log .EXAMPLE PS C:\> Get-D365RunbookLogFile -Path "C:\Temp\PU35" -Step 34 -OpenInEditor This will locate all logfiles that has been outputted from the Step 34 from the PU35 installation. The Get-D365RunbookLogFile will open all log files in the default text editor. .EXAMPLE PS C:\> Get-D365RunbookLogFile -Path "C:\Temp\PU35" -Step 34 -Latest -OpenInEditor This will locate all logfiles that has been outputted from the Step 34 from the PU35 installation. The output will be limited to the latest log, based on last write time. The Get-D365RunbookLogFile will open the log file in the default text editor. .EXAMPLE PS C:\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnlyAsObjects | Get-D365RunbookLogFile -Path "C:\Temp\PU35" -OpenInEditor This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. The output from Invoke-D365RunbookAnalyzer will only contain failed steps. The Get-D365RunbookLogFile will open all log files for the failed step. .NOTES Tags: Runbook, Servicing, Hotfix, DeployablePackage, Deployable Package, InstallationRecordsDirectory, Installation Records Directory Author: Mötz Jensen (@Splaxi) #> function Get-D365RunbookLogFile { [CmdletBinding()] [OutputType('System.String')] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)] [Alias('File')] [string] $Path, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)] [Alias('StepId')] [string] $Step, [switch] $Latest, [switch] $OpenInEditor ) process { if (-not (Test-PathExists -Path $Path -Type Container)) { return } $stepPath = Get-ChildItem -Path $Path -Filter $step -Recurse -Directory | Select-Object -First 1 if ($null -eq $stepPath) { $messageString = "Couldn't locate a folder with the specified step id." Write-PSFMessage -Level Host -Message $messageString Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) } $files = @(Get-ChildItem -Path "$($stepPath.FullName)\Log\*.log" -Recurse | Sort-Object -Descending { $_.LastWriteTime }) if ($files.Count -lt 1) { $messageString = "Couldn't locate any log files in the folder associated with the step." Write-PSFMessage -Level Host -Message $messageString Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) } if ($Latest) { $files = $files | Select-Object -First 1 } foreach ($obj in $files) { $obj | Select-PSFObject "Name as Filename", "LastWriteTime as LastModified", "Fullname as File" -TypeName "D365FO.TOOLS.FileObject" } if($OpenInEditor) { foreach ($obj in $files) { & "$($obj.Fullname)" } } } } ================================================ FILE: d365fo.tools/functions/get-d365sdpcleanup.ps1 ================================================  <# .SYNOPSIS Get the cleanup retention period .DESCRIPTION Gets the configured retention period before updates are deleted .EXAMPLE PS C:\> Get-D365SDPCleanUp This will get the configured retention period from the registry .NOTES Tags: CleanUp, Retention, Servicing, Cut Off, DeployablePackage, Deployable Package Author: Mötz Jensen (@Splaxi) This cmdlet is based on the findings from Alex Kwitny (@AlexOnDAX) See his blog for more info: http://www.alexondax.com/2018/04/msdyn365fo-how-to-adjust-your.html #> function Get-D365SDPCleanUp { [CmdletBinding()] param ( ) $RegSplat = @{ Path = "HKLM:\SOFTWARE\Microsoft\Dynamics\Deployment\" Name = "CutoffDaysForCleanup" } [PSCustomObject] @{ CutoffDaysForCleanup = $( if (Test-RegistryValue @RegSplat) {Get-ItemPropertyValue @RegSplat} else {""} ) } } ================================================ FILE: d365fo.tools/functions/get-d365sdpdetails.ps1 ================================================  <# .SYNOPSIS Get details from the Software Deployable Package .DESCRIPTION Details details about the inner modules / packages that a Software Deployable Contains .PARAMETER Path Path to the Software Deployable Package that you want to work against The cmdlet supports a path to a zip-file or directory with the unpacked content .EXAMPLE PS C:\> Get-D365SDPDetails -Path 'C:\Temp\RV-10.0.36.44.zip' This will display the basic details about the package. The package is a zip file. A result set example: Platform PlatformVersion Modules -------- --------------- ------- Update55 7.0.6651.92 {@{Name=RapidValue; Version=7.0.6651.92}, @{Name=TCLCommon; Version=7.0.6651.92}, @{Name=TC... .EXAMPLE PS C:\> Get-D365SDPDetails -Path 'C:\Temp\RV-10.0.36.44' This will display the basic details about the package. The package is extracted to a local folder. A result set example: Platform PlatformVersion Modules -------- --------------- ------- Update55 7.0.6651.92 {@{Name=RapidValue; Version=7.0.6651.92}, @{Name=TCLCommon; Version=7.0.6651.92}, @{Name=TC... .EXAMPLE PS C:\> Get-D365SDPDetails -Path 'C:\Temp\RV-10.0.36.44.zip' | Select-Object -ExpandProperty Modules This will display the module details that are part of the package. The package is a zip file. A result set example: Name Version ---- ------- RapidValue 7.0.6651.92 TCLCommon 7.0.6651.92 TCLLabel 7.0.6651.92 .NOTES Author: Mötz Jensen (@Splaxi) #># function Get-D365SDPDetails { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] param ( [Parameter(Mandatory = $True)] [Alias('File')] [string] $Path ) $pathWorkDirectory = "$([System.IO.Path]::GetTempPath())d365fo.tools\$([System.Guid]::NewGuid().Guid)" #Make sure the work path is created and available New-Item -Path $pathWorkDirectory -ItemType Directory -Force -ErrorAction Ignore > $null $pathHotfix = Join-Path -Path $pathWorkDirectory -ChildPath "HotfixInstallationInfo.xml" Invoke-TimeSignal -Start if ($Path.EndsWith(".zip")) { <# If we have a zip file, we'll extract the files, to mimic a folder Will copy to the default Windows temporary folder #> Unblock-File -Path $Path $file = [System.IO.File]::Open($Path, [System.IO.FileMode]::Open) $zipArch = [System.IO.Compression.ZipArchive]::new($file) $zipEntry = $zipArch.GetEntry("HotfixInstallationInfo.xml") if (-not $zipEntry) { $messageString = "Unable to find the HotfixInstallationInfo.xml file inside the archive. It would indicate the $Path isn't a valid software deployable package." Write-PSFMessage -Level Host -Message $messageString Stop-PSFFunction -Message "Stopping because HotfixInstallationInfo.xml wasn't found." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) } if (Test-PSFFunctionInterrupt) { return } [System.IO.Compression.ZipFileExtensions]::ExtractToFile($zipEntry, $pathHotfix, $true) foreach ($nuget in $($zipArch.Entries | Where-Object Fullname -like "AOSService[\/]Packages[\/]*.nupkg")) { $pathNuget = "$pathWorkDirectory\$($nuget.name).zip" # The nuget file contains module name in correct casing [System.IO.Compression.ZipFileExtensions]::ExtractToFile($nuget, $pathNuget, $true) } # Clear out any zip archive objects from memory if ($zipArch) { $zipArch.Dispose() } if ($file) { $file.Close() $file.Dispose() } } else { <# Will copy to the default Windows temporary folder #> Copy-Item -Path "$Path\HotfixInstallationInfo.xml" -Destination $pathHotfix -Force foreach ($nuget in $(Get-ChildItem -Path "$Path\AOSService\Packages\*.nupkg")) { Copy-Item -Path $nuget.FullName -Destination "$pathWorkDirectory\$($nuget.Name).zip" -Force } } if (Test-PSFFunctionInterrupt) { return } [System.Collections.Generic.List[System.Object]] $modules = @() foreach ($nuget in $(Get-ChildItem -Path "$pathWorkDirectory\*.nupkg.zip")) { <# nuget contains a nuspec file nuspec is a XML containing the details we are looking for #> $pathXml = $nuget.FullName + ".nuspec" $fileNuget = [System.IO.File]::Open($nuget.FullName, [System.IO.FileMode]::Open) $zipNuget = [System.IO.Compression.ZipArchive]::new($fileNuget) $zipNugetEntry = $zipNuget.Entries | Where-Object Name -like "*.nuspec" | Select-Object -First 1 [System.IO.Compression.ZipFileExtensions]::ExtractToFile($zipNugetEntry, $pathXml, $true) [xml] $moduleSpec = Get-Content -Path $pathXml -Raw $modules.Add( [PSCustomObject]@{ Name = $moduleSpec.package.metadata.summary Version = $moduleSpec.package.metadata.version } ) # Clear out any inner zip archive objects from memory if ($zipNuget) { $zipNuget.Dispose() } if ($fileNuget) { $fileNuget.Close() $fileNuget.Dispose() } } [xml] $hotfix = Get-Content -Path "$pathWorkDirectory\HotfixInstallationInfo.xml" -Raw [PSCustomObject]@{ Platform = $hotfix.HotfixInstallationInfo.PlatformReleaseDisplayName PlatformVersion = $hotfix.HotfixInstallationInfo.PlatformVersion Modules = $modules } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/get-d365table.ps1 ================================================  <# .SYNOPSIS Get a table .DESCRIPTION Get a table either by TableName (wildcard search allowed) or by TableId .PARAMETER Name Name of the table that you are looking for Accepts wildcards for searching. E.g. -Name "Cust*" Default value is "*" which will search for all tables .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER Id The specific id for the table you are looking for .EXAMPLE PS C:\> Get-D365Table -Name CustTable Will get the details for the CustTable .EXAMPLE PS C:\> Get-D365Table -Id 10347 Will get the details for the table with the id 10347. .NOTES Tags: Table, Tables, AOT, TableId, Development Author: Mötz Jensen (@splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. #> function Get-D365Table { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )] [string[]] $Name = "*", [Parameter(Mandatory = $true, ParameterSetName = 'TableId', Position = 1 )] [int] $Id, [Parameter(Mandatory = $false, Position = 2 )] [string] $DatabaseServer = $Script:DatabaseServer, [Parameter(Mandatory = $false, Position = 3 )] [string] $DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, Position = 4 )] [string] $SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, Position = 5 )] [string] $SqlPwd = $Script:DatabaseUserPassword ) BEGIN {} PROCESS { $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $sqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\get-tables.sql") -join [Environment]::NewLine $dataTable = New-Object system.Data.DataSet $dataAdapter = New-Object system.Data.SqlClient.SqlDataAdapter($sqlCommand) $dataAdapter.fill($dataTable) | Out-Null foreach ($localName in $Name) { if ($PSCmdlet.ParameterSetName -eq "Default") { foreach ($obj in $dataTable.Tables.Rows) { if ($obj.AotName -NotLike $localName) { continue } [PSCustomObject]@{ TableId = $obj.TableId TableName = $obj.AotName SqlName = $obj.SqlName } } } else { $obj = $dataTable.Tables.Rows | Where-Object TableId -eq $Id | Select-Object -First 1 [PSCustomObject]@{ TableId = $obj.TableId TableName = $obj.AotName SqlName = $obj.SqlName } } } } END {} } ================================================ FILE: d365fo.tools/functions/get-d365tablefield.ps1 ================================================  <# .SYNOPSIS Get a field from table .DESCRIPTION Get a field either by FieldName (wildcard search allowed) or by FieldId .PARAMETER TableId The id of the table that the field belongs to .PARAMETER Name Name of the field that you are looking for Accepts wildcards for searching. E.g. -Name "Account*" Default value is "*" which will search for all fields .PARAMETER FieldId Id of the field that you are looking for Type is integer .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER TableName Name of the table that the field belongs to Search will only return the first hit (unordered) and work against that hit .PARAMETER IncludeTableDetails Switch options to enable the result set to include extended details .PARAMETER SearchAcrossTables Switch options to force the cmdlet to search across all tables when looking for the field .EXAMPLE PS C:\> Get-D365TableField -TableId 10347 Will get all field details for the table with id 10347. .EXAMPLE PS C:\> Get-D365TableField -TableName CustTable Will get all field details for the CustTable table. .EXAMPLE PS C:\> Get-D365TableField -TableId 10347 -FieldId 175 Will get the details for the field with id 175 that belongs to the table with id 10347. .EXAMPLE PS C:\> Get-D365TableField -TableId 10347 -Name "VATNUM" Will get the details for the "VATNUM" that belongs to the table with id 10347. .EXAMPLE PS C:\> Get-D365TableField -TableId 10347 -Name "VAT*" Will get the details for all fields that fits the search "VAT*" that belongs to the table with id 10347. .EXAMPLE PS C:\> Get-D365TableField -Name AccountNum -SearchAcrossTables Will search for the AccountNum field across all tables. .EXAMPLE PS C:\> Get-D365TableField -TableName CustTable -IncludeTableDetails Will get all field details for the CustTable table. Will include table details in the output. .NOTES Tags: Table, Tables, Fields, TableField, Table Field, TableName, TableId Author: Mötz Jensen (@splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. #> function Get-D365TableField { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 1 )] [int] $TableId, [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )] [Parameter(Mandatory = $false, ParameterSetName = 'TableName', Position = 2 )] [Parameter(Mandatory = $false, ParameterSetName = 'SearchByNameForce', Position = 1 )] [string] $Name = "*", [Parameter(Mandatory = $false, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 3 )] [Parameter(Mandatory = $false, ParameterSetName = 'TableName', ValueFromPipelineByPropertyName = $true, Position = 3 )] [int] $FieldId, [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 4 )] [Parameter(Mandatory = $false, ParameterSetName = 'TableName', Position = 4 )] [Parameter(Mandatory = $false, ParameterSetName = 'SearchByNameForce', Position = 3 )] [string] $DatabaseServer = $Script:DatabaseServer, [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 5 )] [Parameter(Mandatory = $false, ParameterSetName = 'TableName', Position = 5 )] [Parameter(Mandatory = $false, ParameterSetName = 'SearchByNameForce', Position = 4 )] [string] $DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 6 )] [Parameter(Mandatory = $false, ParameterSetName = 'TableName', Position = 6 )] [Parameter(Mandatory = $false, ParameterSetName = 'SearchByNameForce', Position = 5 )] [string] $SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 7 )] [Parameter(Mandatory = $false, ParameterSetName = 'TableName', Position = 7 )] [Parameter(Mandatory = $false, ParameterSetName = 'SearchByNameForce', Position = 6 )] [string] $SqlPwd = $Script:DatabaseUserPassword, [Parameter(Mandatory = $true, ParameterSetName = 'TableName', Position = 1 )] [string] $TableName, [Parameter(Mandatory = $false, ParameterSetName = 'Default')] [Parameter(Mandatory = $false, ParameterSetName = 'TableName')] [switch] $IncludeTableDetails, [Parameter(Mandatory = $true, ParameterSetName = 'SearchByNameForce', Position = 2 )] [switch] $SearchAcrossTables ) BEGIN { $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $sqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection } PROCESS { if ($PSCmdlet.ParameterSetName -eq "TableName") { $TableId = (Get-D365Table -Name $TableName | Select-Object -First 1).TableId } if ($SearchAcrossTables) { $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\get-alltablefields.sql") -join [Environment]::NewLine } else { $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\get-tablefields.sql") -join [Environment]::NewLine $null = $sqlCommand.Parameters.Add("@TableId", $TableId) } $dataTable = New-Object system.Data.DataSet $dataAdapter = New-Object system.Data.SqlClient.SqlDataAdapter($sqlCommand) $dataAdapter.fill($dataTable) | Out-Null foreach ($obj in $dataTable.Tables.Rows) { if ($obj.FieldId -eq 0) { $TableName = $obj.AotName continue } if ($PSBoundParameters.ContainsKey("FieldId")) { if ($obj.FieldId -NotLike $FieldId) { continue } } else { if ($obj.AotName -NotLike $Name) { continue } } $res = [PSCustomObject]@{ FieldId = $obj.FieldId FieldName = $obj.AotName SqlName = $obj.SqlName } if ($IncludeTableDetails) { $res | Add-Member -MemberType NoteProperty -Name 'TableId' -Value $obj.TableId $res | Add-Member -MemberType NoteProperty -Name 'TableName' -Value $TableName } if ($SearchAcrossTables) { $res | Add-Member -MemberType NoteProperty -Name 'TableId' -Value $obj.TableId } $res } } END {} } ================================================ FILE: d365fo.tools/functions/get-d365tablesequence.ps1 ================================================  <# .SYNOPSIS Get the sequence object for table .DESCRIPTION Get the sequence details for tables .PARAMETER TableName Name of the table that you want to work against Accepts wildcards for searching. E.g. -TableName "Cust*" Default value is "*" which will search for all tables .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .EXAMPLE PS C:\> Get-D365TableSequence | Format-Table This will get all the sequence details for all tables inside the database. It will format the output as a table for better overview. .EXAMPLE PS C:\> Get-D365TableSequence -TableName "Custtable" | Format-Table This will get the sequence details for the CustTable in the database. It will format the output as a table for better overview. .EXAMPLE PS C:\> Get-D365TableSequence -TableName "Cust*" | Format-Table This will get the sequence details for all tables that matches the search "Cust*" in the database. It will format the output as a table for better overview. .EXAMPLE PS C:\> Get-D365Table -Name CustTable | Get-D365TableSequence | Format-Table This will get the table details from the Get-D365Table cmdlet and pipe that into Get-D365TableSequence. This will get the sequence details for the CustTable in the database. It will format the output as a table for better overview. .NOTES Tags: Table, RecId, Sequence, Record Id Author: Mötz Jensen (@Splaxi) #> function Get-D365TableSequence { [CmdletBinding()] param ( [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true, Position = 1 )] [Alias('Name')] [string] $TableName = "*", [Parameter(Mandatory = $false, Position = 2 )] [string] $DatabaseServer = $Script:DatabaseServer, [Parameter(Mandatory = $false, Position = 3 )] [string] $DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, Position = 4 )] [string] $SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, Position = 5 )] [string] $SqlPwd = $Script:DatabaseUserPassword ) BEGIN {} PROCESS { $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\get-tablesequence.sql") -join [Environment]::NewLine $null = $sqlCommand.Parameters.AddWithValue('@TableName', $TableName.Replace("*", "%")) $datatable = New-Object system.Data.DataSet $dataadapter = New-Object system.Data.SqlClient.SqlDataAdapter($sqlcommand) $dataadapter.fill($datatable) | Out-Null foreach ($obj in $datatable.Tables.Rows) { $res = [PSCustomObject]@{ SequenceName = $obj.sequence_name TableName = $obj.table_name StartValue = $obj.start_value Increment = $obj.increment MinimumValue = $obj.minimum_value MaximumValue = $obj.maximum_value IsCached = $obj.is_cached CacheSize = $obj.cache_size CurrentValue = $obj.current_value } $res } } END {} } ================================================ FILE: d365fo.tools/functions/get-d365tablesinchangedtracking.ps1 ================================================  <# .SYNOPSIS Get table that is taking part of Change Tracking .DESCRIPTION Get table(s) that is taking part of the SQL Server Change Tracking mechanism .PARAMETER Name Name of the table that you are looking for Accepts wildcards for searching. E.g. -Name "Cust*" Default value is "*" which will search for all tables .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .EXAMPLE PS C:\> Get-D365TablesInChangedTracking This will list all tables that are taking part in the SQL Server Change Tracking. .EXAMPLE PS C:\> Get-D365TablesInChangedTracking -Name CustTable This will search for a table in the list of tables that are taking part in the SQL Server Change Tracking. It will use the CustTable as the search pattern while searching for the table. .NOTES Tags: Table, Change Tracking, Tablename, DMF, DIXF Author: Mötz Jensen (@splaxi) #> function Get-D365TablesInChangedTracking { [CmdletBinding()] param ( [string] $Name = "*", [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword ) PROCESS { $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $sqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection $commandText = (Get-Content "$script:ModuleRoot\internal\sql\get-tablesinchangedtracking.sql") -join [Environment]::NewLine $commandText = $commandText.Replace('@DATABASENAME', $DatabaseName) $sqlCommand.CommandText = $commandText $dataTable = New-Object system.Data.DataSet $dataAdapter = New-Object system.Data.SqlClient.SqlDataAdapter($sqlCommand) $dataAdapter.fill($dataTable) | Out-Null foreach ($obj in $dataTable.Tables.Rows) { if ($obj.name -NotLike $Name) { continue } [PSCustomObject]@{ TableName = $obj.name } } } } ================================================ FILE: d365fo.tools/functions/get-d365tfsuri.ps1 ================================================  <# .SYNOPSIS Get the TFS / VSTS registered URL / URI .DESCRIPTION Gets the URI from the configuration of the local tfs connection in visual studio .PARAMETER Path Path to the tf.exe file that the cmdlet will invoke .EXAMPLE PS C:\> Get-D365TfsUri This will invoke the default tf.exe client located in the Visual Studio 2015 directory and fetch the configured URI. .NOTES Tags: TFS, VSTS, URL, URI, Servicing, Development Author: Mötz Jensen (@Splaxi) #> function Get-D365TfsUri { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )] [string]$Path = $Script:TfDir ) $executable = Join-Path $Path "tf.exe" if (!(Test-PathExists -Path $executable -Type Leaf)) {return} Write-PSFMessage -Level Verbose -Message "Invoking tf.exe" #* Small hack to get the output from the execution into a variable. $res = & $executable "settings" "connections" 2>$null Write-PSFMessage -Level Verbose -Message "Result from tf.exe: $res" -Target $res if (![string]::IsNullOrEmpty($res)) { [PSCustomObject]@{ TfsUri = $res[2].Split(" ")[0] } } else { Write-PSFMessage -Level Host -Message "No TFS / VSTS connections found. It looks like you haven't configured the server connection and workspace yet." } } ================================================ FILE: d365fo.tools/functions/get-d365tfsworkspace.ps1 ================================================  <# .SYNOPSIS Get the TFS / VSTS registered workspace path .DESCRIPTION Gets the workspace path from the configuration of the local tfs in visual studio .PARAMETER Path Path to the directory where the Team Foundation Client executable is located .PARAMETER TfsUri Uri to the TFS / VSTS that the workspace is connected to .EXAMPLE PS C:\> Get-D365TfsWorkspace -TfsUri https://PROJECT.visualstudio.com This will invoke the default tf.exe client located in the Visual Studio 2015 directory and fetch the configured URI. .NOTES Tags: TFS, VSTS, URL, URI, Servicing, Development Author: Mötz Jensen (@Splaxi) #> function Get-D365TfsWorkspace { [CmdletBinding()] param ( [string] $Path = $Script:TfDir, [Parameter(ValueFromPipelineByPropertyName = $true)] [string] $TfsUri = $Script:TfsUri ) process { $executable = Join-Path $Path "tf.exe" if (!(Test-PathExists -Path $executable -Type Leaf)) { return } if ([system.string]::IsNullOrEmpty($TfsUri)) { Write-PSFMessage -Level Host -Message "The supplied uri was empty. Please update the active d365 environment configuration or simply supply the -TfsUri to the cmdlet." Stop-PSFFunction -Message "Stopping because TFS URI is missing." return } Write-PSFMessage -Level Verbose -Message "Invoking tf.exe" #* Small hack to get the output from the execution into a variable. $res = & $executable "vc" "workspaces" "/collection:$TfsUri" "/format:detailed" 2>$null if (![string]::IsNullOrEmpty($res)) { [PSCustomObject]@{ TfsWorkspacePath = ($res | select-string "meta").ToString().Trim().Split(" ")[1] } } else { 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." } } } ================================================ FILE: d365fo.tools/functions/get-d365url.ps1 ================================================  <# .SYNOPSIS Get the url for accessing the instance .DESCRIPTION Get the complete URL for accessing the Dynamics 365 Finance & Operations instance running on this machine .PARAMETER Force Switch to instruct the cmdlet to retrieve the name from the system files instead of the name stored in memory after loading this module. .EXAMPLE PS C:\> Get-D365Url This will get the correct URL to access the environment .NOTES Tags: URL, URI, Servicing Author: Rasmus Andersen (@ITRasmus) The cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations. The call to the dll file gets all registered URL for the environment. #> function Get-D365Url { [CmdletBinding()] param ( [switch] $Force ) if ($Force) { $Url = "https://$($(Get-D365EnvironmentSettings).Infrastructure.FullyQualifiedDomainName)" } else { $Url = $Script:Url } [PSCustomObject]@{ Url = $Url } } ================================================ FILE: d365fo.tools/functions/get-d365user.ps1 ================================================  <# .SYNOPSIS Get users from the environment .DESCRIPTION Get all relevant user details from the Dynamics 365 for Finance & Operations .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER Email The search string to select which user(s) should be updated The parameter supports wildcards. E.g. -Email "*@contoso.com*" Default value is "*" to get all users .PARAMETER ExcludeSystemUsers Instructs the cmdlet to filter out all known system users .EXAMPLE PS C:\> Get-D365User This will get all users from the environment. .EXAMPLE PS C:\> Get-D365User -ExcludeSystemUsers This will get all users from the environment, but filter out all known system user accounts. .EXAMPLE PS C:\> Get-D365User -Email "*contoso.com" This will search for all users with an e-mail address containing 'contoso.com' from the environment. .NOTES Tags: User, Users Author: Mötz Jensen (@Splaxi) Author: Rasmus Andersen (@ITRasmus) #> function Get-D365User { [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 1)] [string]$DatabaseServer = $Script:DatabaseServer, [Parameter(Mandatory = $false, Position = 2)] [string]$DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, Position = 3)] [string]$SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, Position = 4)] [string]$SqlPwd = $Script:DatabaseUserPassword, [Parameter(Mandatory = $false, Position = 5)] [string]$Email = "*", [switch]$ExcludeSystemUsers ) $exclude = @("DAXMDSRunner.com", "dynamics.com") $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\get-user.sql") -join [Environment]::NewLine $null = $sqlCommand.Parameters.Add("@Email", $Email.Replace("*", "%")) try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $reader = $sqlCommand.ExecuteReader() while ($reader.Read() -eq $true) { $res = [PSCustomObject]@{ UserId = "$($reader.GetString($($reader.GetOrdinal("ID"))))" Name = "$($reader.GetString($($reader.GetOrdinal("NAME"))))" NetworkAlias = "$($reader.GetString($($reader.GetOrdinal("NETWORKALIAS"))))" NetworkDomain = "$($reader.GetString($($reader.GetOrdinal("NETWORKDOMAIN"))))" Sid = "$($reader.GetString($($reader.GetOrdinal("SID"))))" IdentityProvider = "$($reader.GetString($($reader.GetOrdinal("IDENTITYPROVIDER"))))" Enabled = [bool][int]"$($reader.GetInt32($($reader.GetOrdinal("ENABLE"))))" Email = "$($reader.GetString($($reader.GetOrdinal("NETWORKALIAS"))))" Company = "$($reader.GetString($($reader.GetOrdinal("COMPANY"))))" } if ($ExcludeSystemUsers) { $temp = $res.Email.Split("@")[1] if ($exclude -contains $temp) { continue } elseif ($res.UserId -eq 'Guest') { continue } } $res } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { $reader.close() if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } } ================================================ FILE: d365fo.tools/functions/get-d365userauthenticationdetail.ps1 ================================================  <# .SYNOPSIS Cmdlet used to get authentication details about a user .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 & Operations .PARAMETER Email The e-mail address / login name of the user that the cmdlet must gather details about .EXAMPLE PS C:\> Get-D365UserAuthenticationDetail -Email "Claire@contoso.com" This will get all the authentication details for the user account with the email address "Claire@contoso.com" .NOTES Tags: User, Users, Security, Configuration, Authentication Author : Rasmus Andersen (@ITRasmus) Author : Mötz Jensen (@splaxi) #> function Get-D365UserAuthenticationDetail { param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [string] $Email ) process { $instanceProvider = Get-InstanceIdentityProvider [string]$identityProvider = Get-CanonicalIdentityProvider $networkDomain = Get-NetworkDomain $Email $instanceProviderName = $instanceProvider.TrimEnd('/') $instanceProviderName = $instanceProviderName.Substring($instanceProviderName.LastIndexOf('/') + 1) $instanceProviderIdentityProvider = Get-IdentityProvider "sample@$instanceProviderName" $emailIdentityProvider = Get-IdentityProvider $Email if ($instanceProviderIdentityProvider -ne $emailIdentityProvider) { $identityProvider = $emailIdentityProvider } $SID = Get-UserSIDFromAad $Email $identityProvider @{"SID" = $SID "NetworkDomain" = $networkDomain "IdentityProvider" = $identityProvider "InstanceProvider" = $instanceProvider } } } ================================================ FILE: d365fo.tools/functions/get-d365visualstudiocompilerresult.ps1 ================================================  <# .SYNOPSIS Get the compiler outputs presented .DESCRIPTION Get the Visual Studio compiler outputs presented in a structured manner on the screen .PARAMETER Module Name of the module that you want to work against Default value is "*" which will search for all modules .PARAMETER ErrorsOnly Instructs the cmdlet to only output compile results where there was errors detected .PARAMETER OutputTotals Instructs the cmdlet to output the total errors and warnings after the analysis .PARAMETER OutputAsObjects Instructs the cmdlet to output the objects instead of formatting them 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 .PARAMETER PackageDirectory Path to the directory containing the installed package / module Default path is the same as the AOS service "PackagesLocalDirectory" directory Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Get-D365VisualStudioCompilerResult This will return the compiler output for all modules. A result set example: File Warnings Errors ---- -------- ------ K:\AosService\PackagesLocalDirectory\ApplicationCommon\BuildModelResult.log 55 0 K:\AosService\PackagesLocalDirectory\ApplicationFoundation\BuildModelResult.log 692 0 K:\AosService\PackagesLocalDirectory\ApplicationPlatform\BuildModelResult.log 155 0 K:\AosService\PackagesLocalDirectory\ApplicationSuite\BuildModelResult.log 10916 0 K:\AosService\PackagesLocalDirectory\CustomModule\BuildModelResult.log 1 2 .EXAMPLE PS C:\> Get-D365VisualStudioCompilerResult -ErrorsOnly This will return the compiler output for all modules where there was errors in. A result set example: File Warnings Errors ---- -------- ------ K:\AosService\PackagesLocalDirectory\CustomModule\BuildModelResult.log 1 2 .EXAMPLE PS C:\> Get-D365VisualStudioCompilerResult -ErrorsOnly -OutputAsObjects This will return the compiler output for all modules where there was errors in. The output will be PSObjects, which can be assigned to a variable and used for futher analysis. A result set example: File Warnings Errors ---- -------- ------ K:\AosService\PackagesLocalDirectory\CustomModule\BuildModelResult.log 1 2 .EXAMPLE PS C:\> Get-D365VisualStudioCompilerResult -OutputTotals This will return the compiler output for all modules and write a total overview to the console. A result set example: File Warnings Errors ---- -------- ------ K:\AosService\PackagesLocalDirectory\ApplicationCommon\BuildModelResult.log 55 0 K:\AosService\PackagesLocalDirectory\ApplicationFoundation\BuildModelResult.log 692 0 K:\AosService\PackagesLocalDirectory\ApplicationPlatform\BuildModelResult.log 155 0 K:\AosService\PackagesLocalDirectory\ApplicationSuite\BuildModelResult.log 10916 0 K:\AosService\PackagesLocalDirectory\CustomModule\BuildModelResult.log 1 2 Total Errors: 2 Total Warnings: 11819 .NOTES Tags: Compiler, Build, Errors, Warnings, Tasks Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Vilmos Kintera" (twitter: @DAXRunBase) All credits goes to him for showing how to extract these information His blog can be found here: https://www.daxrunbase.com/blog/ The specific blog post that we based this cmdlet on can be found here: https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/ The github repository containing the original scrips can be found here: https://github.com/DAXRunBase/PowerShell-and-Azure #> function Get-D365VisualStudioCompilerResult { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')] [OutputType('[PsCustomObject]')] param ( [Alias("ModuleName")] [string] $Module = "*", [switch] $ErrorsOnly, [switch] $OutputTotals, [switch] $OutputAsObjects, [string] $PackageDirectory = $Script:PackageDirectory ) Invoke-TimeSignal -Start if (-not (Test-PathExists -Path $PackageDirectory -Type Container)) { return } $buildOutputFiles = Get-ChildItem -Path "$PackageDirectory\$Module\BuildModelResult.log" -ErrorAction SilentlyContinue -Force $outputCollection = New-Object System.Collections.Generic.List[System.Object] foreach ($result in $buildOutputFiles) { $res = Get-CompilerResult -Path $result.FullName if ($null -ne $res) { $outputCollection.Add($res) } } $totalErrors = 0 $totalWarnings = 0 $resCol = @($outputCollection.ToArray()) $totalWarnings = ($resCol | Measure-Object -Property Warnings -Sum).Sum $totalErrors = ($resCol | Measure-Object -Property Errors -Sum).Sum if ($ErrorsOnly) { $resCol = @($resCol | Where-Object Errors -gt 0) } if ($OutputAsObjects) { $resCol } else { $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' } } if ($OutputTotals) { Write-PSFHostColor -String "Total Errors: $totalErrors" Write-PSFHostColor -String "Total Warnings: $totalWarnings" } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/get-d365webservertype.ps1 ================================================  <# .SYNOPSIS Get the default web server to be used .DESCRIPTION Get the web server which will be used to run D365FO: Either IIS or IIS Express. Newly deployed development machines will have this set to IIS Express by default. It will look for the file located in the default Package Directory. .EXAMPLE PS C:\> Get-D365WebServerType This will display the current web server type registered in the "DynamicsDevConfig.xml" file. Located in "K:\AosService\PackagesLocalDirectory\bin". .NOTES Tag: Web Server, IIS, IIS Express, Development Author: Sander Holvoet (@smholvoet) Author: Mötz Jensen (@Splaxi) #> function Get-D365WebServerType { [CmdletBinding()] param () if (-not ($script:IsAdminRuntime)) { Write-PSFMessage -Level Host -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." Stop-PSFFunction -Message "Stopping because the function is not run elevated" return } $filePath = Join-Path -Path (Join-Path -Path $Script:PackageDirectory -ChildPath "bin") -ChildPath $Script:DevConfig if (-not (Test-PathExists -Path $filePath -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } $namespace = @{ns = "http://schemas.microsoft.com/dynamics/2012/03/development/configuration" } $runtimeHostType = Select-Xml -XPath "/ns:DynamicsDevConfig/ns:RuntimeHostType" -Path $filePath -Namespace $namespace $runtimeHostTypeValue = $runtimeHostType.Node.InnerText [PSCustomObject] @{RuntimeHostType = $runtimeHostTypeValue } } ================================================ FILE: d365fo.tools/functions/get-d365windowsactivationstatus.ps1 ================================================  <# .SYNOPSIS Get activation status .DESCRIPTION Get all the important license and activation information from the machine .EXAMPLE PS C:\> Get-D365WindowsActivationStatus This will get the remaining grace and rearm activation information for the machine .NOTES Tags: Windows, License, Activation, Arm, Rearm Author: Mötz Jensen (@Splaxi) The cmdlet uses CIM objects to access the activation details #> function Get-D365WindowsActivationStatus { [CmdletBinding()] param () begin {} process { $a = Get-CimInstance -Class SoftwareLicensingProduct -Namespace root/cimv2 -ComputerName . -Filter "Name LIKE '%Windows%'" $b = Get-CimInstance -Class SoftwareLicensingService -Namespace root/cimv2 -ComputerName . $res = [PSCustomObject]@{ Name = $a.Name Description = $a.Description "Grace Periode (days)" = [math]::Round(($a.graceperiodremaining / 1440)) } $res | Add-Member -MemberType NoteProperty -Name 'ReArms left' -Value $b.RemainingWindowsReArmCount $res } end {} } ================================================ FILE: d365fo.tools/functions/import-d365aadapplication.ps1 ================================================  <# .SYNOPSIS Used to import Aad applications into D365FO .DESCRIPTION Provides a method for importing a AAD application into D365FO. .PARAMETER Name The name that the imported application should have inside the D365FO environment .PARAMETER UserId The id of the user linked to the application inside the D365FO environment .PARAMETER ClientId The Client ID that the imported application should use inside the D365FO environment .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .EXAMPLE PS C:\> Import-D365AadApplication -Name "Application1" -UserId "admin" -ClientId "aef2e67c-64a3-4c72-9294-d288c5bf503d" Imports Application1 as an application linked to user admin into the D365FO environment. .NOTES Tags: User, Users, Security, Configuration, Permission, AAD, Azure Active Directory, Group, Groups Author: Gert Van Der Heyden (@gertvdheyden) At no circumstances can this cmdlet be used to import users into a PROD environment. #> function Import-D365AadApplication { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [String] $Name, [Parameter(Mandatory = $true)] [string] $UserId, [Parameter(Mandatory = $true)] [string] $ClientId, [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword ) $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection try { $sqlCommand.Connection.Open() Import-AadApplicationIntoD365FO $SqlCommand $Name $UserId $ClientId } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } } ================================================ FILE: d365fo.tools/functions/import-d365aaduser.ps1 ================================================  <# .SYNOPSIS Used to import Aad users into D365FO .DESCRIPTION Provides a method for importing a AAD UserGroup or a comma separated list of AadUsers into D365FO. .PARAMETER AadGroupName Azure Active directory user group containing users to be imported .PARAMETER Users Array of users that you want to import into the D365FO environment .PARAMETER StartupCompany Startup company of users imported. Default is DAT .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER IdPrefix A text that will be prefixed into the ID field. E.g. -IdPrefix "EXT-" will import users and set ID starting with "EXT-..." .PARAMETER NameSuffix A text that will be suffixed into the NAME field. E.g. -NameSuffix "(Contoso)" will import users and append "(Contoso)"" to the NAME .PARAMETER IdValue Specify which field to use as ID value when importing the users. Available options 'Login' / 'FirstName' / 'UserPrincipalName' Default is 'Login' .PARAMETER NameValue Specify which field to use as NAME value when importing the users. Available options 'FirstName' / 'DisplayName' Default is 'DisplayName' .PARAMETER AzureAdCredential Use a PSCredential object for connecting with AzureAd .PARAMETER SkipAzureAd Switch to instruct the cmdlet to skip validating against the Azure Active Directory .PARAMETER ForceExactAadGroupName Force to find the exact name of the Azure Active Directory Group .PARAMETER AadGroupId Azure Active directory user group ID containing users to be imported .PARAMETER EmailValue Specify which field to use as EMAIL value when importing the users. Available options 'Mail' / 'UserPrincipalName' Default is 'Mail' .PARAMETER TenantId The TenantId to use when connecting to Azure Active Directory Uses the tenant id of the current environment if not specified. .EXAMPLE PS C:\> Import-D365AadUser -Users "Claire@contoso.com","Allen@contoso.com" Imports Claire and Allen as users .EXAMPLE PS C:\> $myPassword = ConvertTo-SecureString "MyPasswordIsSecret" -AsPlainText -Force PS C:\> $myCredentials = New-Object System.Management.Automation.PSCredential ("MyEmailIsAlso", $myPassword) PS C:\> Import-D365AadUser -Users "Claire@contoso.com","Allen@contoso.com" -AzureAdCredential $myCredentials This will import Claire and Allen as users. .EXAMPLE PS C:\> Import-D365AadUser -AadGroupName "CustomerTeam1" if more than one group match the AadGroupName, you can use the ExactAadGroupName parameter Import-D365AadUser -AadGroupName "CustomerTeam1" -ForceExactAadGroupName .EXAMPLE PS C:\> Import-D365AadUser -AadGroupName "CustomerTeam1" -ForceExactAadGroupName This is used to force the cmdlet to find the exact named group in Azure Active Directory. .EXAMPLE PS C:\> Import-D365AadUser -AadGroupId "99999999-aaaa-bbbb-cccc-9999999999" Imports all the users that is present in the AAD Group called CustomerTeam1 .EXAMPLE PS C:\> Import-D365AadUser -Users "Claire@contoso.com","Allen@contoso.com" -SkipAzureAd Imports Claire and Allen as users. Will NOT make you connect to the Azure Active Directory(AAD). The needed details will be based on the e-mail address only, and the rest will be blanked. .EXAMPLE PS C:\> Import-D365AadUser -Users "Claire@contoso.com","Allen@contoso.com" -TenantId "99999999-aaaa-bbbb-cccc-9999999999" Imports Claire and Allen as users. Uses tenant id "99999999-aaaa-bbbb-cccc-9999999999" when connecting to Azure Active Directory(AAD). .NOTES Tags: User, Users, Security, Configuration, Permission, AAD, Azure Active Directory, Group, Groups Author: Rasmus Andersen (@ITRasmus) Author: Charles Colombel (@dropshind) Author: Mötz Jensen (@Splaxi) Author: Miklós Molnár (@scifimiki) Author: Gert Van der Heyden (@gertvdh) Author: Florian Hopfner (@FH-Inway) At no circumstances can this cmdlet be used to import users into a PROD environment. Only users from an Azure Active Directory that you have access to, can be imported. Use AAD B2B implementation if you want to support external people. Every imported users will get the System Administration / Administrator role assigned on import #> function Import-D365AadUser { [CmdletBinding(DefaultParameterSetName = 'UserListImport')] param ( [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "GroupNameImport")] [String] $AadGroupName, [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "UserListImport")] [string[]]$Users, [Parameter(Mandatory = $false, Position = 2)] [string] $StartupCompany = 'DAT', [Parameter(Mandatory = $false, Position = 3)] [string] $DatabaseServer = $Script:DatabaseServer, [Parameter(Mandatory = $false, Position = 4)] [string] $DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, Position = 5)] [string] $SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, Position = 6)] [string] $SqlPwd = $Script:DatabaseUserPassword, [Parameter(Mandatory = $false, Position = 7)] [string] $IdPrefix = "", [Parameter(Mandatory = $false, Position = 8)] [string] $NameSuffix = "", [Parameter(Mandatory = $false, Position = 9)] [ValidateSet('Login', 'FirstName', 'UserPrincipalName')] [string] $IdValue = "Login", [Parameter(Mandatory = $false, Position = 10)] [ValidateSet('FirstName', 'DisplayName')] [string] $NameValue = "DisplayName", [Parameter(Mandatory = $false, Position = 11)] [PSCredential] $AzureAdCredential, [Parameter(Mandatory = $false, Position = 12, ParameterSetName = "UserListImport")] [switch] $SkipAzureAd, [Parameter(Mandatory = $false, Position = 13, ParameterSetName = "GroupNameImport")] [switch] $ForceExactAadGroupName, [Parameter(Mandatory = $true, Position = 14, ParameterSetName = "GroupIdImport")] [string] $AadGroupId, [Parameter(Mandatory = $false, Position = 15)] [ValidateSet('Mail', 'UserPrincipalName')] [string] $EmailValue = "Mail", [Parameter(Mandatory = $false, Position = 16)] [string] $TenantId = $Script:TenantId ) $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection $instanceProvider = Get-InstanceIdentityProvider $canonicalProvider = Get-CanonicalIdentityProvider try { Write-PSFMessage -Level Verbose -Message "Trying to connect to the Azure Active Directory with tenant id '$TenantId'" if ($PSBoundParameters.ContainsKey("AzureAdCredential") -eq $true) { Connect-AzAccount -Credential $AzureAdCredential -ErrorAction Stop -TenantId $TenantId } else { if ($SkipAzureAd -eq $false) { Connect-AzAccount -ErrorAction Stop -TenantId $TenantId } } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while connecting to Azure Active Directory" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } $azureAdUsers = New-Object -TypeName "System.Collections.ArrayList" $aadUserProperties = @{ Property = "Id as ObjectId", "mail", "givenName", "displayName", "userPrincipalName" } if (( $PSCmdlet.ParameterSetName -eq "GroupNameImport") -or ($PSCmdlet.ParameterSetName -eq "GroupIdImport")) { if ($PSCmdlet.ParameterSetName -eq 'GroupIdImport') { Write-PSFMessage -Level Verbose -Message "Search AadGroup by its ID : $AadGroupId" $resObj = Invoke-AzRestMethod -Uri "https://graph.microsoft.com/v1.0/groups/$AadGroupId" if ($resObj.StatusCode -like "2**") { $group = $resObj.Content | ConvertFrom-Json } } else { if ($ForceExactAadGroupName) { Write-PSFMessage -Level Verbose -Message "Search AadGroup by its exactly name : $AadGroupName" $resObj = Invoke-AzRestMethod -Uri "https://graph.microsoft.com/v1.0/groups?`$filter=DisplayName eq '$AadGroupName'" if ($resObj.StatusCode -like "2**") { $group = $resObj.Content | ConvertFrom-Json | Select-Object -ExpandProperty value } } else { Write-PSFMessage -Level Verbose -Message "Search AadGroup by searching with its name : $AadGroupName" $resObj = Invoke-AzRestMethod -Uri "https://graph.microsoft.com/v1.0/groups?`$filter=startswith(DisplayName,'$AadGroupName')" if ($resObj.StatusCode -like "2**") { $group = $resObj.Content | ConvertFrom-Json | Select-Object -ExpandProperty value } } } if ($null -eq $group) { 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." Stop-PSFFunction -Message "Stopping because of errors" return } else { Write-PSFMessage -Level Host -Message "Processing Azure AD user Group `"$($group[0].DisplayName)`"" } if ($group.Length -gt 1) { Write-PSFMessage -Level Host -Message "More than one group found" foreach ($foundGroup in $group) { Write-PSFMessage -Level Host -Message "Group found $($foundGroup.DisplayName)" } Stop-PSFFunction -Message "Stopping because of errors" return } $resMembersObj = Invoke-AzRestMethod -Uri "https://graph.microsoft.com/v1.0/groups/$($group.id)/members" if ($resMembersObj.StatusCode -like "2**") { $userlist = $resMembersObj.Content | ConvertFrom-Json | Select-Object -ExpandProperty value } foreach ($user in $userlist) { if ($user.'@odata.type' -eq "#microsoft.graph.user") { $resObj = Invoke-AzRestMethod -Uri "https://graph.microsoft.com/v1.0/users/$($user.id)" if ($resObj.StatusCode -like "2**") { $azureAdUser = $resObj.Content | ConvertFrom-Json | Select-Object -First 1 | Select-PSFObject @aadUserProperties } if ($null -eq $azureAdUser.mail) { Write-PSFMessage -Level Critical "User $($user.ObjectId) did not have an Mail" } else { $null = $azureAdUsers.Add($azureAdUser) } } } } else { foreach ($user in $Users) { if ($SkipAzureAd -eq $true) { $name = Get-LoginFromEmail $user $null = $azureAdUsers.Add([PSCustomObject]@{ mail = $user givenName = $name displayName = $name ObjectId = '' userPrincipalName = $user }) } else { $resObj = Invoke-AzRestMethod -Uri "https://graph.microsoft.com/v1.0/users?`$filter=mail eq '$user' or userPrincipalName eq '$user'" if ($resObj.StatusCode -like "2**") { $aadUser = $resObj.Content | ConvertFrom-Json | Select-Object -ExpandProperty value | Select-Object -First 1 | Select-PSFObject @aadUserProperties } if ($null -eq $aadUser) { Write-PSFMessage -Level Critical "Could not find user $user in AzureAAd" } else { $null = $azureAdUsers.Add($aadUser) } } } } try { $sqlCommand.Connection.Open() foreach ($user in $azureAdUsers) { $identityProvider = $canonicalProvider Write-PSFMessage -Level Verbose -Message "Getting tenant from $($user.Mail)." $tenant = Get-TenantFromEmail $user.Mail Write-PSFMessage -Level Verbose -Message "Getting domain from $($user.Mail)." $networkDomain = Get-NetworkDomain $user.Mail Write-PSFMessage -Level Verbose -Message "InstanceProvider : $InstanceProvider" Write-PSFMessage -Level Verbose -Message "Tenant : $Tenant" if ($user.Mail.ToLower().Contains("outlook.com") -eq $true) { $identityProvider = "live.com" } else { if ($instanceProvider.ToLower().Contains($tenant.ToLower()) -ne $True) { Write-PSFMessage -Level Verbose -Message "Getting identity provider from $($user.Mail)." $identityProvider = Get-IdentityProvider $user.Mail } } Write-PSFMessage -Level Verbose -Message "Getting sid from $($user.Mail) and identity provider : $identityProvider." $sid = Get-UserSIDFromAad $user.Mail $identityProvider Write-PSFMessage -Level Verbose -Message "Generated SID : $sid" $id = "" if ($IdValue -eq 'Login') { $id = $IdPrefix + $(Get-LoginFromEmail $user.Mail) } elseif ($IdValue -eq 'UserPrincipalName') { $id = $IdPrefix + $user.UserPrincipalName } else { $id = $IdPrefix + $user.GivenName } if ($id.Length -gt 20) { $oldId = $id $id = $id -replace '^(.{0,20}).*', '$1' Write-PSFMessage -Level Host -Message "The id '$oldId' does not fit the 20 character limit on UserInfo table's ID field and will be truncated to '$id'" } $name = "" if ($NameValue -eq 'DisplayName') { $name = $user.DisplayName + $NameSuffix } else { $name = $user.GivenName + $NameSuffix } $email = "" if ($EmailValue -eq 'Mail') { $email = $user.Mail } else { $email = $user.UserPrincipalName } Write-PSFMessage -Level Verbose -Message "Id for user $email : $id" Write-PSFMessage -Level Verbose -Message "Name for user $email : $name" Write-PSFMessage -Level Verbose -Message "Importing $email - SID $sid - Provider $identityProvider" Import-AadUserIntoD365FO $SqlCommand $email $name $id $sid $StartupCompany $identityProvider $networkDomain $user.ObjectId if (Test-PSFFunctionInterrupt) { return } } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } } ================================================ FILE: d365fo.tools/functions/import-d365bacpac.ps1 ================================================  <# .SYNOPSIS Import a bacpac file .DESCRIPTION Import a bacpac file to either a Tier1 or Tier2 environment .PARAMETER ImportModeTier1 Switch to instruct the cmdlet that it will import into a Tier1 environment The cmdlet will expect to work against a SQL Server instance .PARAMETER ImportModeTier2 Switch to instruct the cmdlet that it will import into a Tier2 environment The cmdlet will expect to work against an Azure DB instance .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER BacpacFile Path to the bacpac file you want to import into the database server .PARAMETER NewDatabaseName Name of the new database that will be created while importing the bacpac file This will create a new database on the database server and import the content of the bacpac into .PARAMETER AxDeployExtUserPwd Password that is obtained from LCS .PARAMETER AxDbAdminPwd Password that is obtained from LCS .PARAMETER AxRuntimeUserPwd Password that is obtained from LCS .PARAMETER AxMrRuntimeUserPwd Password that is obtained from LCS .PARAMETER AxRetailRuntimeUserPwd Password that is obtained from LCS .PARAMETER AxRetailDataSyncUserPwd Password that is obtained from LCS .PARAMETER AxDbReadonlyUserPwd Password that is obtained from LCS .PARAMETER CustomSqlFile Path to the sql script file that you want the cmdlet to execute against your data after it has been imported .PARAMETER ModelFile Path to the model file that you want the SqlPackage.exe to use instead the one being part of the bacpac file This is used to override SQL Server options, like collation and etc .PARAMETER DiagnosticFile Path to where you want the import to output a diagnostics file to assist you in troubleshooting the import .PARAMETER ImportOnly Switch to instruct the cmdlet to only import the bacpac into the new database The cmdlet will create a new database and import the content of the bacpac file into this Nothing else will be executed .PARAMETER MaxParallelism Sets SqlPackage.exe's degree of parallelism for concurrent operations running against a database The default value is 8 .PARAMETER LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .PARAMETER Properties String array of properties to be used by SQLPackage.exe See https://learn.microsoft.com/en-us/sql/tools/sqlpackage/sqlpackage-import#properties-specific-to-the-import-action for more information. Note that some properties are already set by the cmdlet, and cannot be overridden. .EXAMPLE PS C:\> Invoke-D365InstallSqlPackage You should always install the latest version of the SqlPackage.exe, which is used by New-D365Bacpac. This will fetch the latest .Net Core Version of SqlPackage.exe and install it at "C:\temp\d365fo.tools\SqlPackage". .EXAMPLE PS C:\> Import-D365Bacpac -ImportModeTier1 -BacpacFile "C:\temp\uat.bacpac" -NewDatabaseName "ImportedDatabase" PS C:\> Switch-D365ActiveDatabase -NewDatabaseName "ImportedDatabase" This will instruct the cmdlet that the import will be working against a SQL Server instance. It will import the "C:\temp\uat.bacpac" file into a new database named "ImportedDatabase". The next thing to do is to switch the active database out with the new one you just imported. "ImportedDatabase" will be switched in as the active database, while the old one will be named "AXDB_original". .EXAMPLE 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" PS C:\> Switch-D365ActiveDatabase -NewDatabaseName "ImportedDatabase" -SqlUser "sqladmin" -SqlPwd "XyzXyz" This will instruct the cmdlet that the import will be working against an Azure DB instance. It requires all relevant passwords from LCS for all the builtin user accounts used in a Tier 2 environment. It will import the "C:\temp\uat.bacpac" file into a new database named "ImportedDatabase". The next thing to do is to switch the active database out with the new one you just imported. "ImportedDatabase" will be switched in as the active database, while the old one will be named "AXDB_original". .EXAMPLE PS C:\> Import-D365Bacpac -ImportModeTier1 -BacpacFile "C:\temp\uat.bacpac" -NewDatabaseName "ImportedDatabase" -DiagnosticFile "C:\temp\ImportLog.txt" This will instruct the cmdlet that the import will be working against a SQL Server instance. It will import the "C:\temp\uat.bacpac" file into a new database named "ImportedDatabase". It will output a diagnostic file to "C:\temp\ImportLog.txt". .EXAMPLE PS C:\> Import-D365Bacpac -ImportModeTier1 -BacpacFile "C:\temp\uat.bacpac" -NewDatabaseName "ImportedDatabase" -DiagnosticFile "C:\temp\ImportLog.txt" -MaxParallelism 32 This will instruct the cmdlet that the import will be working against a SQL Server instance. It will import the "C:\temp\uat.bacpac" file into a new database named "ImportedDatabase". It will output a diagnostic file to "C:\temp\ImportLog.txt". It will use 32 connections against the database server while importing the bacpac file. .EXAMPLE PS C:\> Import-D365Bacpac -ImportModeTier1 -BacpacFile "C:\temp\uat.bacpac" -NewDatabaseName "ImportedDatabase" -ImportOnly This will instruct the cmdlet that the import will be working against a SQL Server instance. It will import the "C:\temp\uat.bacpac" file into a new database named "ImportedDatabase". No cleanup or prepping jobs will be executed, because this is for importing only. This would be something that you can use when extract a bacpac file from a Tier1 and want to import it into a Tier1. You would still need to execute the Switch-D365ActiveDatabase cmdlet, to get the newly imported database to be the AXDB database. .EXAMPLE PS C:\> [System.Collections.ArrayList] $PropertiesList = New-Object -TypeName "System.Collections.ArrayList" PS C:\> $PropertiesList.Add("DisableIndexesForDataPhase=false") PS C:\> Import-D365Bacpac -ImportModeTier1 -BacpacFile "C:\temp\uat.bacpac" -NewDatabaseName "ImportedDatabase" -Properties $PropertiesList.ToArray() This will instruct the cmdlet that the import will be working against a SQL Server instance. It will import the "C:\temp\uat.bacpac" file into a new database named "ImportedDatabase". It will use the DisableIndexesForDataPhase SQLPackage property to disable the index rebuild during the data phase of the import. .NOTES Tags: Database, Bacpac, Tier1, Tier2, Golden Config, Config, Configuration Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Import-D365Bacpac { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseProcessBlockForPipelineCommand", "")] [CmdletBinding(DefaultParameterSetName = 'ImportTier1')] param ( [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier1', Position = 0)] [switch] $ImportModeTier1, [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', Position = 0)] [Parameter(Mandatory = $true, ParameterSetName = 'ImportOnlyTier2', Position = 0)] [switch] $ImportModeTier2, [Parameter(Position = 1 )] [string] $DatabaseServer = $Script:DatabaseServer, [Parameter(Position = 2 )] [string] $DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, Position = 3 )] [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 3)] [Parameter(Mandatory = $false, ParameterSetName = 'ImportTier1', Position = 3)] [Parameter(Mandatory = $true, ParameterSetName = 'ImportOnlyTier2', ValueFromPipelineByPropertyName = $true, Position = 3)] [string] $SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, Position = 4 )] [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 4)] [Parameter(Mandatory = $false, ParameterSetName = 'ImportTier1', Position = 4)] [Parameter(Mandatory = $true, ParameterSetName = 'ImportOnlyTier2', ValueFromPipelineByPropertyName = $true, Position = 4)] [string] $SqlPwd = $Script:DatabaseUserPassword, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 5 )] [Alias('File')] [string] $BacpacFile, [Parameter(Mandatory = $true, Position = 6 )] [string] $NewDatabaseName, [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 7)] [Parameter(Mandatory = $false, ParameterSetName = 'ImportOnlyTier2', Position = 7)] [string] $AxDeployExtUserPwd, [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 8)] [Parameter(Mandatory = $false, ParameterSetName = 'ImportOnlyTier2', Position = 8)] [string] $AxDbAdminPwd, [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 9)] [Parameter(Mandatory = $false, ParameterSetName = 'ImportOnlyTier2', Position = 9)] [string] $AxRuntimeUserPwd, [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 10)] [Parameter(Mandatory = $false, ParameterSetName = 'ImportOnlyTier2', Position = 10)] [string] $AxMrRuntimeUserPwd, [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 11)] [Parameter(Mandatory = $false, ParameterSetName = 'ImportOnlyTier2', Position = 11)] [string] $AxRetailRuntimeUserPwd, [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 12)] [Parameter(Mandatory = $false, ParameterSetName = 'ImportOnlyTier2', Position = 12)] [string] $AxRetailDataSyncUserPwd, [Parameter(Mandatory = $true, ParameterSetName = 'ImportTier2', ValueFromPipelineByPropertyName = $true, Position = 13)] [Parameter(Mandatory = $false, ParameterSetName = 'ImportOnlyTier2', Position = 13)] [string] $AxDbReadonlyUserPwd, [string] $CustomSqlFile, [string] $ModelFile, [string] $DiagnosticFile, [Parameter(Mandatory = $false, ParameterSetName = 'ImportTier1')] [Parameter(Mandatory = $true, ParameterSetName = 'ImportOnlyTier2')] [switch] $ImportOnly, [int] $MaxParallelism = 8, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ImportBacpac"), [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly, [switch] $EnableException, [string[]] $Properties ) if (-not (Test-PathExists -Path $BacpacFile -Type Leaf)) { return } if ($PSBoundParameters.ContainsKey("CustomSqlFile")) { if (-not (Test-PathExists -Path $CustomSqlFile -Type Leaf)) { return } else { $ExecuteCustomSQL = $true } } Invoke-TimeSignal -Start $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $BaseParams = @{ DatabaseServer = $DatabaseServer DatabaseName = $DatabaseName SqlUser = $SqlUser SqlPwd = $SqlPwd } $ImportParams = @{ Action = "import" FilePath = $BacpacFile MaxParallelism = $MaxParallelism } if (-not [system.string]::IsNullOrEmpty($DiagnosticFile)) { if (-not (Test-PathExists -Path (Split-Path $DiagnosticFile -Parent) -Type Container -Create)) { return } $ImportParams.DiagnosticFile = $DiagnosticFile } if (-not [system.string]::IsNullOrEmpty($ModelFile)) { if (-not (Test-PathExists -Path $ModelFile -Type Leaf)) { return } $ImportParams.ModelFile = $ModelFile } [System.Collections.ArrayList] $PropertiesList = New-Object -TypeName "System.Collections.ArrayList" foreach ($item in $Properties) { $PropertiesList.Add($item) > $null } Write-PSFMessage -Level Verbose "Testing if we are working against a Tier2 / Azure DB" if ($ImportModeTier2) { Write-PSFMessage -Level Verbose "Start collecting the current Azure DB instance settings" $Objectives = Get-AzureServiceObjective @BaseParams if ($null -eq $Objectives) { return } $null = $PropertiesList.Add("DatabaseEdition=$($Objectives.DatabaseEdition)") $null = $PropertiesList.Add("DatabaseServiceObjective=$($Objectives.DatabaseServiceObjective)") } $ImportParams.Properties = $PropertiesList.ToArray() $Params = Get-DeepClone $BaseParams $Params.DatabaseName = $NewDatabaseName $Params.TrustedConnection = $UseTrustedConnection $SqlPackageParams = Get-DeepClone $Params $SqlPackageParams.OutputCommandOnly = $OutputCommandOnly $SqlPackageParams.LogPath = $LogPath $SqlPackageParams.ShowOriginalProgress = $ShowOriginalProgress Write-PSFMessage -Level Verbose "Start importing the bacpac with a new database name and current settings" Invoke-SqlPackage @SqlPackageParams @ImportParams if ($OutputCommandOnly) { return } if ($ImportOnly) { return } if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose "Importing completed" Write-PSFMessage -Level Verbose -Message "Start working on the configuring the new database" if ($ImportModeTier2) { Write-PSFMessage -Level Verbose "Building sql statement to update the imported Azure database" $InstanceValues = Get-InstanceValues @BaseParams -TrustedConnection $UseTrustedConnection if ($null -eq $InstanceValues) { return } $AzureParams = @{ AxDeployExtUserPwd = $AxDeployExtUserPwd; AxDbAdminPwd = $AxDbAdminPwd; AxRuntimeUserPwd = $AxRuntimeUserPwd; AxMrRuntimeUserPwd = $AxMrRuntimeUserPwd; AxRetailRuntimeUserPwd = $AxRetailRuntimeUserPwd; AxRetailDataSyncUserPwd = $AxRetailDataSyncUserPwd; AxDbReadonlyUserPwd = $AxDbReadonlyUserPwd; } $res = Set-AzureBacpacValues @Params @AzureParams @InstanceValues if (-not ($res)) { return } } else { Write-PSFMessage -Level Verbose "Building sql statement to update the imported SQL database" $res = Set-SqlBacpacValues @Params if (-not ($res)) { return } } if ($ExecuteCustomSQL) { Write-PSFMessage -Level Verbose -Message "Invoking the Execution of custom SQL script" $res = Invoke-D365SqlScript @Params -FilePath $CustomSqlFile if (-not ($res)) { return } } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/import-d365dacpac.ps1 ================================================  <# .SYNOPSIS Import dacpac file to a database .DESCRIPTION Import a dacpac file into a database, using the publish feature of SqlPackage.exe If the database doesn't exists, it will be created If the database exists, the publish process from the dacpac file will make sure to align the different tables inside the database .PARAMETER Path Path to the dacpac file that you want to import .PARAMETER ModelFile Path to the model file that you want the SqlPackage.exe to use instead the one being part of the dacpac file This is used to override SQL Server options, like collation and etc This is also used to support single table import / restore from a dacpac file .PARAMETER PublishFile Path to the publish / profile file that contains extended parameters for the SqlPackage.exe assembly .PARAMETER DiagnosticFile Path to where you want the import to output a diagnostics file to assist you in troubleshooting the import .PARAMETER MaxParallelism Sets SqlPackage.exe's degree of parallelism for concurrent operations running against a database The default value is 8 .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Import-D365Dacpac -Path "c:\Temp\AxDB.dacpac" -ModelFile "c:\Temp\dbo.salestable.model.xml" This will import the dacpac file and use the modified model file while doing so. It will use the "c:\Temp\AxDB.dacpac" as the Path parameter. It will use the "c:\Temp\dbo.salestable.model.xml" as the ModelFile parameter. This is used to enable single table restore / publish. .EXAMPLE PS C:\> Import-D365Dacpac -Path "c:\Temp\AxDB.dacpac" -ModelFile "c:\Temp\dbo.salestable.model.xml" -DiagnosticFile "C:\temp\ImportLog.txt" -MaxParallelism 32 This will import the dacpac file and use the modified model file while doing so. It will use the "c:\Temp\AxDB.dacpac" as the Path parameter. It will use the "c:\Temp\dbo.salestable.model.xml" as the ModelFile parameter. It will use the "C:\temp\ImportLog.txt" as the DiagnosticFile parameter, where the diagnostic file will be stored. It will use 32 connections against the database server while importing the bacpac file. This is used to enable single table restore / publish. .EXAMPLE PS C:\> Import-D365Dacpac -Path "c:\Temp\AxDB.dacpac" -PublishFile "c:\Temp\publish.xml" This will import the dacpac file and use the Publish file which contains advanced configuration instructions for SqlPackage.exe. It will use the "c:\Temp\AxDB.dacpac" as the Path parameter. It will use the "c:\Temp\publish.xml" as the PublishFile parameter, which contains advanced configuration instructions for SqlPackage.exe. This is used to enable full restore / publish, but to avoid some of the common pitfalls. .NOTES Tags: Database, Dacpac, Tier1, Tier2, Golden Config, Config, Configuration Author: Mötz Jensen (@Splaxi) #> function Import-D365Dacpac { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [Alias("Dacpac")] [Alias("File")] [string] $Path, [string] $ModelFile, [Alias("ProfileFile")] [string] $PublishFile, [string] $DiagnosticFile, [int] $MaxParallelism = 8, [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ImportDacpac"), [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly, [switch] $EnableException ) if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } Invoke-TimeSignal -Start $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $BaseParams = @{ DatabaseServer = $DatabaseServer DatabaseName = $DatabaseName SqlUser = $SqlUser SqlPwd = $SqlPwd } $ImportParams = @{ Action = "Publish" FilePath = $Path MaxParallelism = $MaxParallelism } if ($DiagnosticFile) { if (-not (Test-PathExists -Path (Split-Path $DiagnosticFile -Parent) -Type Container -Create)) { return } $ImportParams.DiagnosticFile = $DiagnosticFile } if ($ModelFile) { if (-not (Test-PathExists -Path $ModelFile -Type Leaf)) { return } $ImportParams.ModelFile = $ModelFile } if ($PublishFile) { if (-not (Test-PathExists -Path $PublishFile -Type Leaf)) { return } $ImportParams.PublishFile = $PublishFile } if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose "Start publishing the dacpac" Invoke-SqlPackage @BaseParams @ImportParams -TrustedConnection $UseTrustedConnection -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath if ($OutputCommandOnly) { return } if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose "Importing completed" Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/import-d365externaluser.ps1 ================================================  <# .SYNOPSIS Import an user from an external Azure Active Directory (AAD) .DESCRIPTION Imports an user from an AAD that is NOT the same as the AAD tenant that the D365FO environment is running under .PARAMETER Id The internal Id that the user must be imported with The Id has to unique across the entire user base .PARAMETER Name The display name of the user inside the D365FO environment .PARAMETER Email The email address of the user that you want to import This is also the sign-in user name / e-mail address to gain access to the system If the external AAD tenant has multiple custom domain names, you have to use the domain that they have configured as default .PARAMETER Company Default company that should be configured for the user, for when they sign-in to the D365 environment Default value is "DAT" .PARAMETER Language Language that should be configured for the user, for when they sign-in to the D365 environment Default value is "en-US" .PARAMETER Enabled Should the imported user be enabled or not? Default value is 1, which equals true / yes .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .EXAMPLE PS C:\> Import-D365ExternalUser -Id "John" -Name "John Doe" -Email "John@contoso.com" This will import an user from an external Azure Active Directory. The new user will get the system wide Id "John". The name of the new user will be "John Doe". The e-mail address / sign-in e-mail address will be registered as "John@contoso.com". .NOTES Tags: User, Users, Security, Configuration, Permission, AAD, Azure Active Directory Author: Anderson Joyle (@AndersonJoyle) Author: Mötz Jensen (@Splaxi) #> function Import-D365ExternalUser { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $Id, [Parameter(Mandatory = $true)] [string] $Name, [Parameter(Mandatory = $true)] [string] $Email, [Parameter(Mandatory = $false)] [int] $Enabled = 1, [Parameter(Mandatory = $false)] [string] $Company = "DAT", [Parameter(Mandatory = $false)] [string] $Language = "en-us", [Parameter(Mandatory = $false)] [string]$DatabaseServer = $Script:DatabaseServer, [Parameter(Mandatory = $false)] [string]$DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false)] [string]$SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false)] [string]$SqlPwd = $Script:DatabaseUserPassword ) begin { Invoke-TimeSignal -Start $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection try { $sqlCommand.Connection.Open() } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } process { if (Test-PSFFunctionInterrupt) { return } try { $userAuth = Get-D365UserAuthenticationDetail $Email $provider = $userAuth.IdentityProvider $networkDomain = $userAuth.NetworkDomain $sid = $userAuth.SID Write-PSFMessage -Level Verbose -Message "Extracted sid: $sid" Import-AadUserIntoD365FO -SqlCommand $SqlCommand -SignInName $Email -Name $Name -Id $Id -SID $SID -StartUpCompany $Company -IdentityProvider $provider -NetworkDomain $networkDomain -Language $Language if (Test-PSFFunctionInterrupt) { return } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } } end { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/import-d365model.ps1 ================================================  <# .SYNOPSIS Import a model into Dynamics 365 for Finance & Operations .DESCRIPTION Import a model into a Dynamics 365 for Finance & Operations environment .PARAMETER Path Path to the axmodel file that you want to import .PARAMETER Model Name of the model that you want to work against .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin Default value is fetched from the current configuration on the machine .PARAMETER MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory .PARAMETER Replace Instruct the cmdlet to replace an already existing model .PARAMETER LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .EXAMPLE PS C:\> Import-D365Model -Path c:\temp\d365fo.tools\CustomModel.axmodel This will import the "c:\temp\d365fo.tools\CustomModel.axmodel" model into the PackagesLocalDirectory location. .EXAMPLE PS C:\> Import-D365Model -Path c:\temp\d365fo.tools\CustomModel.axmodel -Replace This will import the "c:\temp\d365fo.tools\CustomModel.axmodel" model into the PackagesLocalDirectory location. If the model already exists it will replace it. .NOTES Tags: ModelUtil, Axmodel, Model, Import, Replace, Source Control, Vsts, Azure DevOps Author: Mötz Jensen (@Splaxi) #> function Import-D365Model { # [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueSwitchParameter", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $True, Position = 1 )] [Alias('File')] [string] $Path, [Parameter(Mandatory = $false, Position = 2 )] [string] $BinDir = "$Script:PackageDirectory\bin", [Parameter(Mandatory = $false, Position = 3 )] [string] $MetaDataDir = "$Script:MetaDataDir", [switch] $Replace, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ModelUtilImport"), [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) Invoke-TimeSignal -Start if($Replace) { Invoke-ModelUtil -Command "Replace" -Path $Path -BinDir $BinDir -MetaDataDir $MetaDataDir -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath } else { Invoke-ModelUtil -Command "Import" -Path $Path -BinDir $BinDir -MetaDataDir $MetaDataDir -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/import-d365rsatselfservicecertificates.ps1 ================================================  <# .SYNOPSIS Import certificates for RSAT .DESCRIPTION Import the certificates for RSAT into the correct stores and display the thumbprint 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 .PARAMETER Path Path to the folder where the .cer and .pxf files are located The files needs to be extracted from the zip archive .PARAMETER Password Password for the .pxf file Working with self-service environments, the password will be displayed during the download of the zip archive .EXAMPLE PS C:\> Import-D365RsatSelfServiceCertificates -Path "C:\Temp\UAT" -Password "123456789" This will import the .cer and .pxf files into the correct store, bases on the files located in "C:\Temp\UAT". After import it will display the thumbprint for both certificates. Sample output: [23:43:05][Import-D365RsatSelfServiceCertificates] Pfx Thumbprint: B4D6921321434235463463414312343253523A05 [23:43:05][Import-D365RsatSelfServiceCertificates] Cert Thumbprint: B4D6921321434235463463414312343253523A05 .NOTES Author: Mötz Jensen (@Splaxi) #> function Import-D365RsatSelfServiceCertificates { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param ( [Parameter( Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [string] $Path, [Parameter( Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [string] $Password ) begin { } process { [Security.SecureString] $PasswordSecure = (ConvertTo-SecureString -String $Password -Force -AsPlainText) if (-not (Test-PathExists -Path $Path -Type Container)) { return } if (Test-PSFFunctionInterrupt) { return } $pathCertFile = (Get-ChildItem -Path "$Path\*.cer" | Select-Object -First 1).FullName $pathPfxFile = (Get-ChildItem -Path "$Path\*.pfx" | Select-Object -First 1).FullName if (-not $pathCertFile -or -not $pathPfxFile) { $messageString = "One of the certificate files are missing. Make sure that the path you supplied contains a set of .cer and .pxf certificate files." Write-PSFMessage -Level Host -Message $messageString Stop-PSFFunction -Message "Stopping because an generic error message." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) return } $pxfCert = Import-PfxCertificate -FilePath $pathPfxFile -CertStoreLocation "Cert:\LocalMachine\Root" -Password $PasswordSecure Import-PfxCertificate -FilePath $pathPfxFile -CertStoreLocation "Cert:\LocalMachine\My" -Password $PasswordSecure > $null $cert = Import-Certificate -FilePath $pathCertFile -CertStoreLocation "Cert:\LocalMachine\Root" Import-Certificate -FilePath $pathCertFile -CertStoreLocation "Cert:\LocalMachine\My" > $null Write-PSFMessage -Level Host -Message "Pfx Thumbprint: $($pxfCert.Thumbprint)" Write-PSFMessage -Level Host -Message "Cert Thumbprint: $($cert.Thumbprint)" } end { } } ================================================ FILE: d365fo.tools/functions/initialize-d365rsatcertificate.ps1 ================================================  <# .SYNOPSIS Create and configure test automation certificate .DESCRIPTION Creates a new self signed certificate for automated testing and reconfigures the AOS Windows Identity Foundation configuration to trust the certificate .PARAMETER CertificateFileName Filename to be used when exporting the cer file .PARAMETER PrivateKeyFileName Filename to be used when exporting the pfx file .PARAMETER Password The password that you want to use to protect your certificate with The default value is: "Password1" .PARAMETER CertificateOnly Switch specifying if only the certificate needs to be created If specified, then only the certificate is created and the thumbprint is not added to the wif.config on the AOS side 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 .PARAMETER KeepCertificateFile Instruct the cmdlet to copy the certificate file from the working directory into the desired location specified with OutputPath parameter .PARAMETER OutputPath Path to where you want the certificate file exported to, when using the KeepCertificateFile parameter switch Default value is: "c:\temp\d365fo.tools" .EXAMPLE PS C:\> Initialize-D365RsatCertificate 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. .EXAMPLE PS C:\> Initialize-D365RsatCertificate -CertificateOnly This will generate a certificate for issuer 127.0.0.1 and install it in the trusted root certificates. No actions will be taken regarding modifying the AOS wif.config file. Use this when installing RSAT on a machine different from the AOS where RSAT is pointing to. .EXAMPLE PS C:\> Initialize-D365RsatCertificate -CertificateOnly -KeepCertificateFile This will generate a certificate for issuer 127.0.0.1 and install it in the trusted root certificates. No actions will be taken regarding modifying the AOS wif.config file. The pfx will be copied into the default "c:\temp\d365fo.tools" folder after creation. Use this when installing RSAT on a machine different from the AOS where RSAT is pointing to. The pfx file enables you to import the same certificate across your entire network, instead of creating one per machine. .NOTES Tags: Automated Test, Test, Regression, Certificate, Thumbprint Author: Kenny Saelen (@kennysaelen) Author: Mötz Jensen (@Splaxi) #> function Initialize-D365RsatCertificate { [Alias("Initialize-D365TestAutomationCertificate")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingCmdletAliases", "")] [CmdletBinding()] param ( [string] $CertificateFileName = (Join-Path $env:TEMP "TestAuthCert.cer"), [string] $PrivateKeyFileName = (Join-Path $env:TEMP "TestAuthCert.pfx"), [Security.SecureString] $Password = (ConvertTo-SecureString -String "Password1" -Force -AsPlainText), [switch] $CertificateOnly, [Parameter(ParameterSetName = "KeepCertificateFile")] [switch] $KeepCertificateFile, [Parameter(ParameterSetName = "KeepCertificateFile")] [string] $OutputPath = $Script:DefaultTempPath ) if (-not $Script:IsAdminRuntime) { 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." Stop-PSFFunction -Message "Elevated permissions needed. Please start an elevated session and run the cmdlet again." return } try { # Create the certificate and place it in the right stores $X509Certificate = New-D365SelfSignedCertificate -CertificateFileName $CertificateFileName -PrivateKeyFileName $PrivateKeyFileName -Password $Password if (Test-PSFFunctionInterrupt) { Write-PSFMessage -Level Critical -Message "The self signed certificate creation was interrupted." Stop-PSFFunction -Message "Stopping because of errors." return } if($false -eq $CertificateOnly) { # Modify the wif.config of the AOS to have this thumbprint added to the https://fakeacs.accesscontrol.windows.net/ authority Add-D365RsatWifConfigAuthorityThumbprint -CertificateThumbprint $X509Certificate.Thumbprint } # Write-PSFMessage -Level Host -Message "Generated certificate: $X509Certificate" if($KeepCertificateFile){ $PrivateKeyFileName = ($PrivateKeyFileName | Copy-Item -Destination $OutputPath -PassThru).FullName } [PSCustomObject]@{ File = $PrivateKeyFileName Filename = $(Split-Path -Path $PrivateKeyFileName -Leaf) } $X509Certificate | Format-Table Thumbprint, Subject, FriendlyName, NotAfter } catch { Write-PSFMessage -Level Host -Message "Something went wrong while configuring the certificates and the Windows Identity Foundation configuration for the AOS" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } ================================================ FILE: d365fo.tools/functions/install-d365supportingsoftware.ps1 ================================================  <# .SYNOPSIS Install software supporting F&O development .DESCRIPTION Installs software commonly used when doing Dynamics 365 Finance and Operations development Common ones: fiddler, postman, microsoft-edge, winmerge, notepadplusplus.install, azurepowershell, azure-cli, insomnia-rest-api-client, git.install Full list of software: https://community.chocolatey.org/packages .PARAMETER Name The name of the software to install Support a list of softwares that you want to have installed on the system .PARAMETER Force Instruct the cmdlet to install the latest version of the software, regardless if it is already present on the system .EXAMPLE PS C:\> Install-D365SupportingSoftware -Name vscode This will install VSCode on the system. .EXAMPLE PS C:\> Install-D365SupportingSoftware -Name "vscode","fiddler" This will install VSCode and fiddler on the system. .EXAMPLE PS C:\> Install-D365SupportingSoftware -Name vscode -Force This will install VSCode on the system, forcing it to be (re)installed. .NOTES Author: Dag Calafell (@dodiggitydag) Author: Mötz Jensen (@Splaxi) #> function Install-D365SupportingSoftware { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingInvokeExpression", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [Alias('SoftwareName')] [string[]] $Name, [switch] $Force ) BEGIN { try { if (Test-Path -Path "$env:ProgramData\Chocolatey") { choco upgrade chocolatey -y -r choco upgrade all --ignore-checksums -y -r } else { Write-PSFMessage -Level InternalComment -Message "Installing Chocolatey" # Download and execute installation script [System.Net.WebRequest]::DefaultWebProxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials Invoke-Expression ((New-Object System.Net.WebClient).DownloadString("https://chocolatey.org/install.ps1")) } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while installing or updating Chocolatey" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } #Determine choco executable location # This is needed because the path variable is not updated in this session yet # This part is copied from https://chocolatey.org/install.ps1 $chocoPath = [Environment]::GetEnvironmentVariable("ChocolateyInstall") if ($chocoPath -eq $null -or $chocoPath -eq '') { $chocoPath = "$env:ALLUSERSPROFILE\Chocolatey" } if (!(Test-Path ($chocoPath))) { $chocoPath = "$env:SYSTEMDRIVE\ProgramData\Chocolatey" } $chocoExePath = Join-Path $chocoPath 'bin\choco.exe' if (-not (Test-PathExists -Path $chocoExePath -Type Leaf)) { return } } PROCESS { if (Test-PSFFunctionInterrupt) { return } try { foreach ($item in $Name) { Write-PSFMessage -Level InternalComment -Message "Installing $item" $params = New-Object System.Collections.Generic.List[System.Object] $params.AddRange(@( "install" "$item", "-y", "-r" )) if ($Force) { $params.Add("-f") } # Use Chocolatey to install the package Invoke-Process -Executable $chocoExePath -Params $($params.ToArray()) -ShowOriginalProgress:$true } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while installing software" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } END { } } ================================================ FILE: d365fo.tools/functions/invoke-d365azcopytransfer.ps1 ================================================  <# .SYNOPSIS Transfer a file using AzCopy .DESCRIPTION Transfer a file using the AzCopy tool You can upload a local file to an Azure Storage Blob Container You can download a file located in an Azure Storage Blob Container to a local folder 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 .PARAMETER SourceUri Source file uri that you want to transfer .PARAMETER DestinationUri Destination file uri that you want to transfer the file to .PARAMETER FileName 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 .PARAMETER DeleteOnTransferComplete Instruct the cmdlet to delete the source file when done transfering Default is $false which will leave the source file .PARAMETER LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .PARAMETER Force Instruct the cmdlet to overwrite already existing file .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE 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" This will transfer a file from an Azure Storage Blob Container to a local folder/file on the machine. The file that will be transfered/downloaded is SourceUri "https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...". The file will be transfered/downloaded to DestinationUri "c:\temp\d365fo.tools\GOLDER.bacpac". If there exists a file already, the file will NOT be overwritten. .EXAMPLE 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 This will transfer a file from an Azure Storage Blob Container to a local folder/file on the machine. The file that will be transfered/downloaded is SourceUri "https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...". The file will be transfered/downloaded to DestinationUri "c:\temp\d365fo.tools\GOLDER.bacpac". If there exists a file already, the file will be overwritten, because Force has been supplied. .EXAMPLE 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=..." This will transfer a file from an Azure Storage Blob Container to another Azure Storage Blob Container. The file that will be transfered/downloaded is SourceUri "https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...". The file will be transfered/downloaded to DestinationUri "https://456.blob.core.windows.net/targetcontainer/filename?sv=2015-12-11&sr=...". For this to work, you need to make sure both SourceUri and DestinationUri has an valid SAS token/key included. If there exists a file already, the file will NOT be overwritten. .EXAMPLE 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 This will transfer a file from an Azure Storage Blob Container to a local folder/file on the machine. The file that will be transfered/downloaded is SourceUri "https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...". The file will be transfered/downloaded to DestinationUri "c:\temp\d365fo.tools\GOLDER.bacpac". 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=...". .EXAMPLE PS C:\> $DestinationParms = Get-D365AzureStorageUrl -OutputAsHashtable PS C:\> $BlobFileDetails = Get-D365LcsDatabaseBackups -Latest | Invoke-D365AzCopyTransfer @DestinationParms PS C:\> $BlobFileDetails | Invoke-D365AzCopyTransfer -DestinationUri "C:\Temp" -DeleteOnTransferComplete This will transfer the lastest backup file from LCS Asset Library to your local "C:\Temp". It will get a destination Url, for it to transfer the backup file between the LCS storage account and your own. The newly transfered file, that lives in your own storage account, will then be downloaded to your local "c:\Temp". After the file has been downloaded to your local "C:\Temp", it will be deleted from your own storage account. .NOTES Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, File, Files, Latest, Bacpac, Container, LCS, Asset, Library Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. #> function Invoke-D365AzCopyTransfer { [CmdletBinding()] param ( [Alias('SourceUrl')] [Alias('FileLocation')] [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string] $SourceUri, [Alias('DestinationFile')] [Parameter(Mandatory = $true)] [string] $DestinationUri, [Parameter(ValueFromPipelineByPropertyName = $true)] [string] $FileName, [switch] $DeleteOnTransferComplete, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\AzCopy"), [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly, [switch] $Force, [switch] $EnableException ) process { $executable = $Script:AzCopyPath Invoke-TimeSignal -Start if (-not [string]::IsNullOrEmpty($FileName)) { if ($DestinationUri -like "*?*") { $DestinationUri = $DestinationUri.Replace("?", "/$FileName`?") } else { if ([System.IO.File]::GetAttributes($DestinationUri).HasFlag([System.IO.FileAttributes]::Directory)) { $DestinationUri = Join-Path -Path $DestinationUri -ChildPath $FileName } } } $params = New-Object System.Collections.Generic.List[string] $params.Add("copy") $params.Add("`"$SourceUri`"") $params.Add("`"$DestinationUri`"") if (-not $Force) { $params.Add("--overwrite=false") } Invoke-Process -Executable $executable -Params $params.ToArray() -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath if (Test-PSFFunctionInterrupt) { return } if ($DeleteOnTransferComplete) { $params = New-Object System.Collections.Generic.List[string] $params.Add("remove") $params.Add("`"$SourceUri`"") Invoke-Process -Executable $executable -Params $params.ToArray() -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly } if ($DestinationUri -notlike "*https*") { $filePath = Get-ChildItem -Path $DestinationUri -Recurse -File | Sort-Object CreationTime -Descending | Select-Object -First 1 $FileName = $filePath.Name } else { $filePath = $DestinationUri } #Filename is missing. If Https / SAS, we need some work. #If local file, it should be easy to solve $res = @{ File = $filePath SourceUri = $filePath PSTypeName = 'D365FO.TOOLS.AZCOPYTRANSFER' } if (-not [string]::IsNullOrEmpty($FileName)) { $res.FileName = $FileName } [PSCustomObject]$res Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/invoke-d365azuredevopsnugetpush.ps1 ================================================  <# .SYNOPSIS Push a package / nuget to Azure DevOps .DESCRIPTION Push a package / nuget to an Azure DevOps feed .PARAMETER Path Path to the package / nuget that you want to push to the Azure DevOps feed .PARAMETER Source The logical name for the nuget source / connection that you want to use while pushing the package / nuget This requires you to register the nuget source, by hand, using the nuget.exe tool directly Base command to use: .\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" Please note that the password is in fact a personal access token and NOT your real password The value specified for Name in the nuget sources command, is the value to supply for Source for this cmdlet .PARAMETER LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Invoke-D365AzureDevOpsNugetPush -Path "c:\temp\d365fo.tools\microsoft.dynamics.ax.application.devalm.buildxpp.10.0.605.10014.nupkg" -Source "Contoso" This will push the package / nuget to the Azure DevOps feed. 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". The request will be going to the Azure DevOps instance that is registered with the Source (Name) "Contoso" via the nuget.exe tool. .NOTES Author: Mötz Jensen (@Splaxi) #> function Invoke-D365AzureDevOpsNugetPush { [CmdletBinding()] param ( [Alias('PackagePath')] [string] $Path, [Alias('Destination')] [Alias('NugetSource')] [string] $Source, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\Nuget"), [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly, [switch] $EnableException ) process { $executable = $Script:NugetPath $params = New-Object System.Collections.Generic.List[string] $params.Add("push") $params.Add("`"$Path`"") $params.Add("-Source") $params.Add("`"$Source`"") $params.Add("-ApiKey") $params.Add("AzureDevOps") Invoke-Process -Executable $executable -Params $params.ToArray() -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath } } ================================================ FILE: d365fo.tools/functions/invoke-d365azurestoragedownload.ps1 ================================================  <# .SYNOPSIS Download a file to Azure .DESCRIPTION Download any file to an Azure Storage Account .PARAMETER AccountId Storage Account Name / Storage Account Id where you want to fetch the file from .PARAMETER AccessToken The token that has the needed permissions for the download action .PARAMETER SAS The SAS key that you have created for the storage account or blob container .PARAMETER Container Name of the blob container inside the storage account you where the file is .PARAMETER FileName Name of the file that you want to download .PARAMETER Path Path to the folder / location you want to save the file The default path is "c:\temp\d365fo.tools" .PARAMETER Latest Instruct the cmdlet to download the latest file from Azure regardless of name .PARAMETER Force Instruct the cmdlet to overwrite the local file if it already exists .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Invoke-D365AzureStorageDownload -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Container "backupfiles" -FileName "OriginalUAT.bacpac" -Path "c:\temp" Will download the "OriginalUAT.bacpac" file from the storage account and save it to "c:\temp\OriginalUAT.bacpac" .EXAMPLE PS C:\> Invoke-D365AzureStorageDownload -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Container "backupfiles" -Path "c:\temp" -Latest Will download the file with the latest modified datetime from the storage account and save it to "c:\temp\". The complete path to the file will returned as output from the cmdlet. .EXAMPLE PS C:\> $AzureParams = Get-D365ActiveAzureStorageConfig PS C:\> Invoke-D365AzureStorageDownload @AzureParams -Path "c:\temp" -Latest This will get the current Azure Storage Account configuration details and use them as parameters to download the latest file from an Azure Storage Account Will download the file with the latest modified datetime from the storage account and save it to "c:\temp\". The complete path to the file will returned as output from the cmdlet. .EXAMPLE PS C:\> Invoke-D365AzureStorageDownload -Latest This will use the default parameter values that are based on the configuration stored inside "Get-D365ActiveAzureStorageConfig". Will download the file with the latest modified datetime from the storage account and save it to "c:\temp\d365fo.tools". .EXAMPLE PS C:\> Invoke-D365AzureStorageDownload -AccountId "miscfiles" -SAS "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" -Container "backupfiles" -Path "c:\temp" -Latest Will download the file with the latest modified datetime from the storage account and save it to "c:\temp\". A SAS key is used to gain access to the container and downloading the file from it. The complete path to the file will returned as output from the cmdlet. .NOTES Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, File, Files, Latest, Bacpac, Container Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. #> function Invoke-D365AzureStorageDownload { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false)] [string] $AccountId = $Script:AzureStorageAccountId, [Parameter(Mandatory = $false)] [string] $AccessToken = $Script:AzureStorageAccessToken, [Parameter(Mandatory = $false)] [string] $SAS = $Script:AzureStorageSAS, [Alias('Blob')] [Alias('Blobname')] [string] $Container = $Script:AzureStorageContainer, [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true)] [Alias('Name')] [string] $FileName, [string] $Path = $Script:DefaultTempPath, [Parameter(Mandatory = $true, ParameterSetName = 'Latest', Position = 4 )] [Alias('GetLatest')] [switch] $Latest, [switch] $Force, [switch] $EnableException ) BEGIN { if (-not (Test-PathExists -Path $Path -Type Container -Create)) { return } if (([string]::IsNullOrEmpty($AccountId) -eq $true) -or ([string]::IsNullOrEmpty($Container)) -or (([string]::IsNullOrEmpty($AccessToken)) -and ([string]::IsNullOrEmpty($SAS)))) { 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." Stop-PSFFunction -Message "Stopping because of missing parameters" return } } PROCESS { if (Test-PSFFunctionInterrupt) { return } Invoke-TimeSignal -Start try { if ([string]::IsNullOrEmpty($SAS)) { Write-PSFMessage -Level Verbose -Message "Working against Azure Storage Account with AccessToken" $storageContext = New-AzStorageContext -StorageAccountName $AccountId.ToLower() -StorageAccountKey $AccessToken } else { Write-PSFMessage -Level Verbose -Message "Working against Azure Storage Account with SAS" $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) $storageContext = New-AzStorageContext -ConnectionString $conString } Write-PSFMessage -Level Verbose -Message "Start download from Azure Storage Account" if ($Latest) { $files = Get-AzStorageBlob -Container $($Container.ToLower()) -Context $storageContext $File = ($files | Sort-Object -Descending { $_.LastModified } | Select-Object -First 1) $FileName = $File.Name Write-PSFMessage -Level Verbose -Message "Filename is: $FileName" $NewFile = Join-Path $Path $($File.Name) $null = Get-AzStorageBlobContent -Container $($Container.ToLower()) -Blob $File.Name -Destination $NewFile -Context $storageContext -Force:$Force } else { Write-PSFMessage -Level Verbose -Message "Filename is: $FileName" $NewFile = Join-Path $Path $FileName $null = Get-AzStorageBlobContent -Container $($Container.ToLower()) -Blob $FileName -Destination $NewFile -Context $storageContext -Force:$Force } Get-Item -Path $NewFile | Select-PSFObject "Name as Filename", @{Name = "Size"; Expression = { [PSFSize]$_.Length } }, "LastWriteTime as LastModified", "Fullname as File" } catch { $messageString = "Something went wrong while downloading the file from Azure." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target $NewFile Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ return } finally { Invoke-TimeSignal -End } } END { } } ================================================ FILE: d365fo.tools/functions/invoke-d365azurestorageupload.ps1 ================================================  <# .SYNOPSIS Upload a file to Azure .DESCRIPTION Upload any file to an Azure Storage Account .PARAMETER AccountId Storage Account Name / Storage Account Id where you want to store the file .PARAMETER AccessToken The token that has the needed permissions for the upload action .PARAMETER SAS The SAS key that you have created for the storage account or blob container .PARAMETER Container Name of the blob container inside the storage account you want to store the file .PARAMETER Filepath Path to the file you want to upload .PARAMETER ContentType Media type of the file that is going to be uploaded The value will be used for the blob property "Content Type". If the parameter is left empty, the commandlet will try to automatically determined the value based on the file's extension. 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. Valid media type values can be found here: https://www.iana.org/assignments/media-types/media-types.xhtml .PARAMETER Force Instruct the cmdlet to overwrite the file in the container if it already exists .PARAMETER DeleteOnUpload Switch to tell the cmdlet if you want the local file to be deleted after the upload completes .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Invoke-D365AzureStorageUpload -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Container "backupfiles" -Filepath "c:\temp\bacpac\UAT_20180701.bacpac" -DeleteOnUpload 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. After upload the local file will be deleted. .EXAMPLE PS C:\> $AzureParams = Get-D365ActiveAzureStorageConfig PS C:\> New-D365Bacpac | Invoke-D365AzureStorageUpload @AzureParams This will get the current Azure Storage Account configuration details and use them as parameters to upload the file to an Azure Storage Account. .EXAMPLE PS C:\> New-D365Bacpac | Invoke-D365AzureStorageUpload This will generate a new bacpac file using the "New-D365Bacpac" cmdlet. The file will be uploaded to an Azure Storage Account using the "Invoke-D365AzureStorageUpload" cmdlet. This will use the default parameter values that are based on the configuration stored inside "Get-D365ActiveAzureStorageConfig" for the "Invoke-D365AzureStorageUpload" cmdlet. .EXAMPLE PS C:\> Invoke-D365AzureStorageUpload -AccountId "miscfiles" -SAS "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" -Container "backupfiles" -Filepath "c:\temp\bacpac\UAT_20180701.bacpac" -DeleteOnUpload This will upload the "c:\temp\bacpac\UAT_20180701.bacpac" up to the "backupfiles" container, inside the "miscfiles" Azure Storage Account. A SAS key is used to gain access to the container and uploading the file to it. .NOTES Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, File, Files, Bacpac, Container Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. #> function Invoke-D365AzureStorageUpload { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false)] [string] $AccountId = $Script:AzureStorageAccountId, [Parameter(Mandatory = $false)] [string] $AccessToken = $Script:AzureStorageAccessToken, [Parameter(Mandatory = $false)] [string] $SAS = $Script:AzureStorageSAS, [Parameter(Mandatory = $false)] [Alias('Blob')] [Alias('Blobname')] [string] $Container = $Script:AzureStorageContainer, [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipeline = $true)] [Parameter(Mandatory = $true, ParameterSetName = 'Pipeline', ValueFromPipelineByPropertyName = $true)] [Alias('File')] [Alias('Path')] [string] $Filepath, [Parameter(Mandatory = $false)] [string] $ContentType, [switch] $Force, [switch] $DeleteOnUpload, [switch] $EnableException ) BEGIN { if (([string]::IsNullOrEmpty($AccountId) -eq $true) -or ([string]::IsNullOrEmpty($Container)) -or (([string]::IsNullOrEmpty($AccessToken)) -and ([string]::IsNullOrEmpty($SAS)))) { 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." Stop-PSFFunction -Message "Stopping because of missing parameters" return } } PROCESS { if (Test-PSFFunctionInterrupt) { return } Invoke-TimeSignal -Start $FileName = Split-Path -Path $Filepath -Leaf try { if ([string]::IsNullOrEmpty($SAS)) { Write-PSFMessage -Level Verbose -Message "Working against Azure Storage Account with AccessToken" $storageContext = New-AzStorageContext -StorageAccountName $AccountId.ToLower() -StorageAccountKey $AccessToken } else { $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) Write-PSFMessage -Level Verbose -Message "Working against Azure Storage Account with SAS" -Target $conString $storageContext = New-AzStorageContext -ConnectionString $conString } Write-PSFMessage -Level Verbose -Message "Start uploading the file to Azure" if ([string]::IsNullOrEmpty($ContentType)) { $ContentType = [System.Web.MimeMapping]::GetMimeMapping($Filepath) # Available since .NET4.5, so it can be used with PowerShell 5.0 and higher. Write-PSFMessage -Level Verbose -Message "Content Type is automatically set to value: $ContentType" } $null = Set-AzStorageBlobContent -Context $storageContext -File $Filepath -Container $($Container.ToLower()) -Properties @{"ContentType" = $ContentType} -Force:$Force if ($DeleteOnUpload) { Remove-Item $Filepath -Force } [PSCustomObject]@{ File = $Filepath Filename = $FileName } } catch { $messageString = "Something went wrong while uploading the file to Azure." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target $FileName Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ return } finally { Invoke-TimeSignal -End } } END { } } ================================================ FILE: d365fo.tools/functions/invoke-d365bestpractice.ps1 ================================================  <# .SYNOPSIS Run the Best Practice .DESCRIPTION Run the Best Practice checks against modules and models .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin .PARAMETER MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory .PARAMETER Module Name of the Module to analyse .PARAMETER Model Name of the Model to analyse .PARAMETER PackagesRoot Instructs the cmdlet to use binary metadata .PARAMETER LogPath Path where you want to store the log outputs generated from the best practice analyser Also used as the path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER RunFixers Instructs the cmdlet to invoke the fixers for the identified warnings .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .EXAMPLE PS C:\> Invoke-D365BestPractice -module "ApplicationSuite" -model "MyOverLayerModel" This will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module. The default output will be silenced. The XML log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.xml". The log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.log". .EXAMPLE PS C:\> Invoke-D365BestPractice -module "ApplicationSuite" -model "MyOverLayerModel" -PackagesRoot This will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module. We use the binary metadata to look for the module and model. The default output will be silenced. The XML log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.xml". The log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.log". .EXAMPLE PS C:\> Invoke-D365BestPractice -module "ApplicationSuite" -model "MyOverLayerModel" -ShowOriginalProgress This will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module. The output from the best practice check process will be written to the console / host. The XML log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.xml". The log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.log". .EXAMPLE PS C:\> Invoke-D365BestPractice -module "ApplicationSuite" -model "MyOverLayerModel" -RunFixers This will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module. The default output will be silenced. The XML log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.xml". The log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.log". Instructs the xppbp tool to run the fixers for all identified warnings. .NOTES Tags: Best Practice, BP, BPs, Module, Model, Quality Author: Gert Van Der Heyden (@gertvdheyden) Author: Mötz Jensen (@Splaxi) #> function Invoke-D365BestPractice { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] [CmdletBinding()] [OutputType('[PsCustomObject]')] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias("ModuleName")] [string] $Module, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('ModelName')] [string] $Model, [string] $BinDir = "$Script:PackageDirectory\bin", [string] $MetaDataDir = "$Script:MetaDataDir", [switch] $PackagesRoot, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\BestPractice"), [switch] $ShowOriginalProgress, [switch] $RunFixers, [switch] $OutputCommandOnly ) begin { Invoke-TimeSignal -Start $tool = "xppbp.exe" $executable = Join-Path -Path $BinDir -ChildPath $tool if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return } if (-not (Test-PathExists -Path $executable -Type Leaf)) { return } } process { if (Test-PSFFunctionInterrupt) { return } $logDirModule = (Join-Path -Path $LogPath -ChildPath $Module) if (-not (Test-PathExists -Path $logDirModule -Type Container -Create)) { return } if (Test-PSFFunctionInterrupt) { return } $logFile = Join-Path -Path $logDirModule -ChildPath "Dynamics.AX.$Model.xppbp.log" $logXmlFile = Join-Path -Path $logDirModule -ChildPath "Dynamics.AX.$Model.xppbp.xml" $params = @( "-metadata=`"$MetaDataDir`"", "-all", "-module=`"$Module`"", "-model=`"$Model`"", "-xmlLog=`"$logXmlFile`"", "-log=`"$logFile`"" ) if ($PackagesRoot -eq $true) { $params += "-packagesroot=`"$MetaDataDir`"" } if ($RunFixers -eq $true) { $params += "-runfixers" } Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $logDirModule if ($OutputCommandOnly) { return } [PSCustomObject]@{ LogFile = $logFile XmlLogFile = $logXmlFile } } end { Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/invoke-d365compilerresultanalyzer.ps1 ================================================  <# .SYNOPSIS Analyze the compiler output log .DESCRIPTION Analyze the compiler output log and generate an excel file contain worksheets per type: Errors, Warnings, Tasks It could be a Visual Studio compiler log or it could be a Invoke-D365ModuleCompile log you want analyzed .PARAMETER Path Path to the compiler log file that you want to work against A BuildModelResult.log or a Dynamics.AX.*.xppc.log file will both work .PARAMETER OutputPath Path where you want the excel file (xlsx-file) saved to .PARAMETER SkipWarnings Instructs the cmdlet to skip warnings while analyzing the compiler output log file .PARAMETER SkipTasks Instructs the cmdlet to skip tasks while analyzing the compiler output log file .PARAMETER PackageDirectory Path to the directory containing the installed package / module Default path is the same as the AOS service "PackagesLocalDirectory" directory Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Invoke-D365CompilerResultAnalyzer -Path "c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log" This will analyse all compiler output log files generated from Visual Studio. It will use the default path for the OutputPath parameter. It will build error and error summary worksheets. It will build warning and warning summary worksheets. It will build task and task summary worksheets. A result set example: File Filename ---- -------- c:\temp\d365fo.tools\Custom-CompilerResults.xlsx Custom-CompilerResults.xlsx .EXAMPLE PS C:\> Invoke-D365CompilerResultAnalyzer -Path "c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log" -SkipWarnings This will analyse all compiler output log files generated from Visual Studio. It will use the default path for the OutputPath parameter. It will build error and error summary worksheets. It will build task and task summary worksheets. A result set example: File Filename ---- -------- c:\temp\d365fo.tools\Custom-CompilerResults.xlsx Custom-CompilerResults.xlsx .EXAMPLE PS C:\> Invoke-D365CompilerResultAnalyzer -Path "c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log" -SkipTasks This will analyse all compiler output log files generated from Visual Studio. It will use the default path for the OutputPath parameter. It will build error and error summary worksheets. It will build warning and warning summary worksheets. A result set example: File Filename ---- -------- c:\temp\d365fo.tools\Custom-CompilerResults.xlsx Custom-CompilerResults.xlsx .NOTES Tags: Compiler, Build, Errors, Warnings, Tasks Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Vilmos Kintera" (twitter: @DAXRunBase) All credits goes to him for showing how to extract these information His blog can be found here: https://www.daxrunbase.com/blog/ The specific blog post that we based this cmdlet on can be found here: https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/ The github repository containing the original scrips can be found here: https://github.com/DAXRunBase/PowerShell-and-Azure #> function Invoke-D365CompilerResultAnalyzer { [CmdletBinding()] [OutputType('')] param ( [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('LogFile')] [string] $Path, [string] $OutputPath = $Script:DefaultTempPath, [switch] $SkipWarnings, [switch] $SkipTasks, [string] $PackageDirectory = $Script:PackageDirectory ) begin { Invoke-TimeSignal -Start if (-not (Test-PathExists -Path $PackageDirectory -Type Container)) { return } } process { $moduleName = "" if($Path -like "*Dynamics.AX.*.xppc.log"){ $splittedString = $Path -split ".*Dynamics.AX.(.*).xppc.log" $moduleName = $splittedString[1] }elseif ($Path -like "*BuildModelResult.log"){ $splittedString = $Path -split ".*\\(.*)\\BuildModelResult.log" $moduleName = $splittedString[1] }else{ $moduleName = (New-Guid).Guid } $outputFilePath = Join-Path -Path $OutputPath -ChildPath "$moduleName-CompilerResults.xlsx" Invoke-CompilerResultAnalyzer -Path $Path -Identifier $moduleName -OutputPath $outputFilePath -SkipWarnings:$SkipWarnings -SkipTasks:$SkipTasks -PackageDirectory $PackageDirectory } end { Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/invoke-d365dataflush.ps1 ================================================  <# .SYNOPSIS Invoke the one of the data flush classes .DESCRIPTION Invoke one of the runnable classes that is clearing cache, data or something else .PARAMETER URL URL to the Dynamics 365 instance you want to clear the AOD cache on .PARAMETER Class The class that you want to execute. Default value is "SysFlushAod" .EXAMPLE PS C:\> Invoke-D365DataFlush This will make a call against the default URL for the machine and have it execute the SysFlushAOD class. .EXAMPLE PS C:\> Invoke-D365DataFlush -Class SysFlushData,SysFlushAod This will make a call against the default URL for the machine and have it execute the SysFlushData and SysFlushAod classes. .NOTES Tags: Flush, Url, Servicing Author: Mötz Jensen (@Splaxi) #> function Invoke-D365DataFlush { [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 1 )] [string] $Url, [ValidateSet('SysFlushData', 'SysFlushAod', 'SysDataCacheParameters')] [string[]] $Class = "SysFlushAod" ) if ($PSBoundParameters.ContainsKey("URL")) { foreach ($item in $Class) { Write-PSFMessage -Level Verbose -Message "Executing Invoke-D365SysRunnerClass with $item" -Target $item Invoke-D365SysRunnerClass -ClassName $item -Url $URL } } else { foreach ($item in $Class) { Write-PSFMessage -Level Verbose -Message "Executing Invoke-D365SysRunnerClass with $item" -Target $item Invoke-D365SysRunnerClass -ClassName $item } } } ================================================ FILE: d365fo.tools/functions/invoke-d365dbsync.ps1 ================================================  <# .SYNOPSIS Invoke the synchronization process used in Visual Studio .DESCRIPTION Uses the sync.exe (engine) to synchronize the database for the environment .PARAMETER BinDirTools Path to where the tools on the machine can be found Default value is normally the AOS Service PackagesLocalDirectory\bin .PARAMETER MetadataDir Path to where the tools on the machine can be found Default value is normally the AOS Service PackagesLocalDirectory .PARAMETER SyncMode The sync mode the sync engine will use Default value is: "FullAll" .PARAMETER Verbosity Parameter used to instruct the level of verbosity the sync engine has to report back Default value is: "Normal" .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .EXAMPLE PS C:\> Invoke-D365DBSync This will invoke the sync engine and have it work against the database. .EXAMPLE PS C:\> Invoke-D365DBSync -Verbose 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. .NOTES Tags: Database, Sync, SyncDB, Synchronization, Servicing Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) When running the 'FullAll' (default) the command requires an elevated console / Run As Administrator. #> function Invoke-D365DbSync { [CmdletBinding()] param ( [string] $BinDirTools = $Script:BinDirTools, [string] $MetadataDir = $Script:MetaDataDir, #[ValidateSet('None', 'PartialList','InitialSchema','FullIds','PreTableViewSyncActions','FullTablesAndViews','PostTableViewSyncActions','KPIs','AnalysisEnums','DropTables','FullSecurity','PartialSecurity','CleanSecurity','ADEs','FullAll','Bootstrap','LegacyIds','Diag')] [string] $SyncMode = 'FullAll', [ValidateSet('Normal', 'Quiet', 'Minimal', 'Normal', 'Detailed', 'Diagnostic')] [string] $Verbosity = 'Normal', [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\DbSync"), [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) Invoke-TimeSignal -Start #! The way the sync engine works is that it uses the connection string for some operations, #! but for FullSync / FullAll it depends on the database details from the same assemblies that #! we rely on. So the testing of how to run this cmdlet is a bit different than others Write-PSFMessage -Level Debug -Message "Testing if run on LocalHostedTier1 and console isn't elevated" if ($Script:EnvironmentType -eq [EnvironmentType]::LocalHostedTier1 -and !$script:IsAdminRuntime) { Write-PSFMessage -Level Host -Message "It seems that you ran this cmdlet non-elevated and on a local VM / local vhd. 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`"" Stop-PSFFunction -Message "Stopping because of missing parameters" return } elseif (!$script:IsAdminRuntime -and $Script:UserIsAdmin -and $Script:EnvironmentType -ne [EnvironmentType]::LocalHostedTier1) { Write-PSFMessage -Level Host -Message "It seems that you ran this cmdlet non-elevated and as an administrator. 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" Stop-PSFFunction -Message "Stopping because of missing parameters" return } $executable = Join-Path -Path $BinDirTools -ChildPath "SyncEngine.exe" if (-not (Test-PathExists -Path $executable -Type Leaf)) { return } if (-not (Test-PathExists -Path $MetadataDir -Type Container)) { return } Write-PSFMessage -Level Debug -Message "Testing if the SyncEngine is already running." $syncEngine = Get-Process -Name "SyncEngine" -ErrorAction SilentlyContinue if ($null -ne $syncEngine) { Write-PSFMessage -Level Host -Message "A instance of SyncEngine is already running. Please wait for it to finish or kill it." Stop-PSFFunction -Message "Stopping because SyncEngine.exe already running" return } Write-PSFMessage -Level Debug -Message "Build the parameters for the command to execute." $params = @("-syncmode=$($SyncMode.ToLower())", "-verbosity=$($Verbosity.ToLower())", "-metadatabinaries=`"$MetadataDir`"", "-connect=`"server=$DatabaseServer;Database=$DatabaseName; User Id=$SqlUser;Password='$SqlPwd';`"" ) Write-PSFMessage -Level Debug -Message "Starting the SyncEngine with the parameters." -Target $param #! We should consider to redirect the standard output & error like this: https://stackoverflow.com/questions/8761888/capturing-standard-out-and-error-with-start-process Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/invoke-d365dbsyncmodule.ps1 ================================================  <# .SYNOPSIS Synchronize all sync base and extension elements based on a modulename .DESCRIPTION Retrieve the list of installed packages / modules where the name fits the ModelName parameter. 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 .PARAMETER Module Name of the model you want to sync tables and table extensions Supports an array of module names .PARAMETER LogPath The path where the log file will be saved .PARAMETER Verbosity Parameter used to instruct the level of verbosity the sync engine has to report back Default value is: "Normal" .PARAMETER BinDirTools Path to where the tools on the machine can be found Default value is normally the AOS Service PackagesLocalDirectory\bin .PARAMETER MetadataDir Path to where the tools on the machine can be found Default value is normally the AOS Service PackagesLocalDirectory .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .EXAMPLE PS C:\> Invoke-D365DbSyncModule -Module "MyModel1" It will start the sync process against all tables, views, data entities, table-extensions, view-extensions and data entities-extensions of MyModel1. .EXAMPLE PS C:\> Invoke-D365DbSyncModule -Module "MyModel1","MyModel2" 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. .EXAMPLE PS C:\> Get-D365Module -Name "MyModel*" | Invoke-D365DbSyncModule Retrieve the list of installed packages / modules where the name fits the search "MyModel*". The result is: MyModel1 MyModel2 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. .NOTES Tags: Database, Sync, SyncDB, Synchronization, Servicing Author: Jasper Callens - Cegeka Author: Caleb Blanchard (@daxcaleb) Author: Mötz Jensen (@Splaxi) #> function Invoke-D365DbSyncModule { [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias("ModuleName")] [string[]] $Module, [ValidateSet('Normal', 'Quiet', 'Minimal', 'Normal', 'Detailed', 'Diagnostic')] [string] $Verbosity = 'Normal', [string] $BinDirTools = $Script:BinDirTools, [string] $MetadataDir = $Script:MetaDataDir, [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\DbSync"), [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) begin { Invoke-TimeSignal -Start [System.Collections.Generic.List[System.String]] $modules = @() } process { foreach ($moduleLocal in $Module) { $modules.Add($moduleLocal) } } end { # Retrieve all sync elements of provided module name $allModelSyncElements = $modules.ToArray() | Get-SyncElements # Build parameters for the partial sync function $syncParams = @{ SyncList = $allModelSyncElements.BaseSyncElements; SyncExtensionsList = $allModelSyncElements.ExtensionSyncElements; Verbosity = $Verbosity; BinDirTools = $BinDirTools; MetadataDir = $MetadataDir; DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd; LogPath = $LogPath; ShowOriginalProgress = $ShowOriginalProgress; OutputCommandOnly = $OutputCommandOnly; } # Call the partial sync using required parameters $resSyncModule = Invoke-D365DBSyncPartial @syncParams $resSyncModule Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/invoke-d365dbsyncpartial.ps1 ================================================  <# .SYNOPSIS Invoke the synchronization process used in Visual Studio .DESCRIPTION Uses the sync.exe (engine) to synchronize the database for the environment .PARAMETER SyncMode The sync mode the sync engine will use Default value is: "PartialList" .PARAMETER SyncList The list of objects that you want to pass on to the database synchronoziation engine .PARAMETER SyncExtensionsList The list of extension objects that you want to pass on to the database synchronoziation engine .PARAMETER Verbosity Parameter used to instruct the level of verbosity the sync engine has to report back Default value is: "Normal" .PARAMETER BinDirTools Path to where the tools on the machine can be found Default value is normally the AOS Service PackagesLocalDirectory\bin .PARAMETER MetadataDir Path to where the tools on the machine can be found Default value is normally the AOS Service PackagesLocalDirectory .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .EXAMPLE PS C:\> Invoke-D365DBSyncPartial -SyncList "CustCustomerEntity","SalesTable" This will invoke the sync engine and have it work against the database. It will run with the default value "PartialList" as the SyncMode. It will run the sync process against "CustCustomerEntity" and "SalesTable" .EXAMPLE PS C:\> Invoke-D365DBSyncPartial -SyncList "CustCustomerEntity","SalesTable" -Verbose This will invoke the sync engine and have it work against the database. It will run with the default value "PartialList" as the SyncMode. It will run the sync process against "CustCustomerEntity" and "SalesTable" It will output the same level of details that Visual Studio would normally do. .EXAMPLE PS C:\> Invoke-D365DBSyncPartial -SyncList "CustCustomerEntity","SalesTable" -SyncExtensionsList "CaseLog.Extension","CategoryTable.Extension" -Verbose This will invoke the sync engine and have it work against the database. It will run with the default value "PartialList" as the SyncMode. It will run the sync process against "CustCustomerEntity", "SalesTable", "CaseLog.Extension" and "CategoryTable.Extension" It will output the same level of details that Visual Studio would normally do. .NOTES Tags: Database, Sync, SyncDB, Synchronization, Servicing Author: Mötz Jensen (@Splaxi) Author: Jasper Callens - Cegeka Inspired by: https://axdynamx.blogspot.com/2017/10/how-to-synchronize-manually-database.html #> function Invoke-D365DbSyncPartial { [CmdletBinding()] param ( [string[]] $SyncList, [string[]] $SyncExtensionsList, #[ValidateSet('None', 'PartialList','InitialSchema','FullIds','PreTableViewSyncActions','FullTablesAndViews','PostTableViewSyncActions','KPIs','AnalysisEnums','DropTables','FullSecurity','PartialSecurity','CleanSecurity','ADEs','FullAll','Bootstrap','LegacyIds','Diag')] [string] $SyncMode = 'PartialList', [ValidateSet('Normal', 'Quiet', 'Minimal', 'Normal', 'Detailed', 'Diagnostic')] [string] $Verbosity = 'Normal', [string] $BinDirTools = $Script:BinDirTools, [string] $MetadataDir = $Script:MetaDataDir, [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\DbSync"), [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) process { Invoke-TimeSignal -Start #! The way the sync engine works is that it uses the connection string for some operations, #! but for FullSync / FullAll it depends on the database details from the same assemblies that #! we rely on. So the testing of how to run this cmdlet is a bit different than others Write-PSFMessage -Level Debug -Message "Testing if run on LocalHostedTier1 and console isn't elevated" if ($Script:EnvironmentType -eq [EnvironmentType]::LocalHostedTier1 -and !$script:IsAdminRuntime) { Write-PSFMessage -Level Host -Message "It seems that you ran this cmdlet non-elevated and on a local VM / local vhd. 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`"" Stop-PSFFunction -Message "Stopping because of missing parameters" return } elseif (!$script:IsAdminRuntime -and $Script:UserIsAdmin -and $Script:EnvironmentType -ne [EnvironmentType]::LocalHostedTier1) { Write-PSFMessage -Level Host -Message "It seems that you ran this cmdlet non-elevated and as an administrator. 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" Stop-PSFFunction -Message "Stopping because of missing parameters" return } $executable = Join-Path -Path $BinDirTools -ChildPath "SyncEngine.exe" if (-not (Test-PathExists -Path $executable -Type Leaf)) { return } if (-not (Test-PathExists -Path $MetadataDir -Type Container)) { return } Write-PSFMessage -Level Debug -Message "Testing if the SyncEngine is already running." $syncEngine = Get-Process -Name "SyncEngine" -ErrorAction SilentlyContinue if ($null -ne $syncEngine) { Write-PSFMessage -Level Host -Message "A instance of SyncEngine is already running. Please wait for it to finish or kill it." Stop-PSFFunction -Message "Stopping because SyncEngine.exe already running" return } Write-PSFMessage -Level Debug -Message "Build the parameters for the command to execute." $params = @("-syncmode=$($SyncMode.ToLower())", "-synclist=`"$($SyncList -join ",")`"", "-tableextensionlist=`"$($SyncExtensionsList -join ',')`"", "-verbosity=$($Verbosity.ToLower())", "-metadatabinaries=`"$MetadataDir`"", "-connect=`"server=$DatabaseServer;Database=$DatabaseName; User Id=$SqlUser;Password=$SqlPwd;`"" ) Write-PSFMessage -Level Debug -Message "Starting the SyncEngine with the parameters." -Target $param #! We should consider to redirect the standard output & error like this: https://stackoverflow.com/questions/8761888/capturing-standard-out-and-error-with-start-process Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/invoke-d365generatereportaggregatedataentity.ps1 ================================================  <# .SYNOPSIS Generate Report for Aggregate Data Entity .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Aggregate Data Entities and generate a metadata report .PARAMETER OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Invoke-D365GenerateReportAggregateDataEntity This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> function Invoke-D365GenerateReportAggregateDataEntity { [CmdletBinding()] param ( [string] $OutputPath = $Script:DefaultTempPath, [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) begin { $outputFile = Join-Path -Path $OutputPath -ChildPath "AggregateDataEntities.xlsx" Import-GenerateReportAssemblies $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $providerConfig.XppMetadataPath = $PackageDirectory $providerConfig.MetadataPath = $PackageDirectory $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig) $productVersionDetails = Get-D365ProductInformation if (-not $productVersionDetails.ApplicationBuildVersion) { $version = $productVersionDetails.ApplicationVersion } else { $version = $productVersionDetails.ApplicationBuildVersion } } process { if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Getting all Aggregate Data Entities via the metadata provider." $aggregateDataEntityModelInfos = $metadataProvider.AggregateDataEntities.GetPrimaryKeysWithModelInfo() $aggregateDataEntities = New-Object System.Collections.Generic.List[object] foreach ($tuple in $aggregateDataEntityModelInfos) { $elementName = $tuple.Item1 Write-PSFMessage -Level Verbose -Message "Working on: $elementName (AggregateDataEntity)" -Target $elementName $modelInfoNames = $tuple.Item2 | Select-Object -ExpandProperty Name # convert list of ModelInfo objects to list of Names $modelNames = [string]::Join("; ", $modelInfoNames); $element = $metadataProvider.AggregateDataEntities.Read($elementName) #filter out system fields $fields = @() foreach ($j in $element.Fields) { if ($j -notlike "AX_*") { $fields += $j } } $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair Name = $element.Name DataSource = $element.AggregateViewDataSource.Measurement Public = $element.IsPublic PublicCollectionName = $element.PublicCollectionName TableGroup = $element.TableGroup EntityCategory = $element.EntityCategory Fields = [string]::Join(", ", $fields) Models = $modelNames } $aggregateDataEntities.Add($outItems) } $reportName = "AggregateDataEntities" $sheetName = "$reportName`_$version" $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length)) $aggregateDataEntities | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName [PSCustomObject]@{ Report = $reportName File = $outputFile Filename = (Split-Path $outputFile -Leaf) } } } ================================================ FILE: d365fo.tools/functions/invoke-d365generatereportaggregatemeasure.ps1 ================================================  <# .SYNOPSIS Generate Report for Aggregate Measure .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Aggregate Measures and generate a metadata report .PARAMETER OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Invoke-D365GenerateReportAggregateMeasure This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> function Invoke-D365GenerateReportAggregateMeasure { [CmdletBinding()] param ( [string] $OutputPath = $Script:DefaultTempPath, [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) begin { $outputFile = Join-Path -Path $OutputPath -ChildPath "AggregateMeasures.xlsx" Write-PSFMessage -Level Verbose -Message "Getting all Aggregate Measures from the internal functions." $aggregateMeasures = Get-AxAggregateMeasures -BinDir $BinDir -PackageDirectory $PackageDirectory $productVersionDetails = Get-D365ProductInformation if (-not $productVersionDetails.ApplicationBuildVersion) { $version = $productVersionDetails.ApplicationVersion } else { $version = $productVersionDetails.ApplicationBuildVersion } } process { if (Test-PSFFunctionInterrupt) { return } $reportName = "AggregateMeasures" $sheetName = "$reportName`_$version" $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length)) $aggregateMeasures | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName [PSCustomObject]@{ Report = $reportName File = $outputFile Filename = (Split-Path $outputFile -Leaf) } } } ================================================ FILE: d365fo.tools/functions/invoke-d365generatereportconfigkey.ps1 ================================================  <# .SYNOPSIS Generate Report for Config Key .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Config Keys and generate a metadata report .PARAMETER OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Invoke-D365GenerateReportConfigKey This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> function Invoke-D365GenerateReportConfigKey { [CmdletBinding()] param ( [string] $OutputPath = $Script:DefaultTempPath, [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) begin { $outputFile = Join-Path -Path $OutputPath -ChildPath "ConfigKeys.xlsx" Import-GenerateReportAssemblies $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $providerConfig.XppMetadataPath = $PackageDirectory $providerConfig.MetadataPath = $PackageDirectory $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig) $productVersionDetails = Get-D365ProductInformation if (-not $productVersionDetails.ApplicationBuildVersion) { $version = $productVersionDetails.ApplicationVersion } else { $version = $productVersionDetails.ApplicationBuildVersion } } process { if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Getting all Configuration Keys via the metadata provider." $configKeyModelInfos = $metadataProvider.ConfigurationKeys.GetPrimaryKeysWithModelInfo() $configKeys = New-Object System.Collections.Generic.List[object] foreach ($tuple in $configKeyModelInfos) { $elementName = $tuple.Item1 Write-PSFMessage -Level Verbose -Message "Working on: $elementName (ConfigurationKey)" -Target $elementName $modelInfoNames = $tuple.Item2 | Select-Object -ExpandProperty Name # convert list of ModelInfo objects to list of Names $modelNames = [string]::Join("; ", $modelInfoNames); $element = $metadataProvider.ConfigurationKeys.Read($elementName) $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair Name = $element.Name Models = $modelNames LicenseCode = $element.LicenseCode ParentKey = $element.ParentKey ConfigKey = $element.ConfigurationKey Enabled = $element.Enabled LabelID = $element.Label Label = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label) } $configKeys.Add($outItems) } $reportName = "ConfigKeys" $sheetName = "$reportName`_$version" $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length)) $configKeys | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName [PSCustomObject]@{ Report = $reportName File = $outputFile Filename = (Split-Path $outputFile -Leaf) } } } ================================================ FILE: d365fo.tools/functions/invoke-d365generatereportconfigkeygroup.ps1 ================================================  <# .SYNOPSIS Generate Report for Config Key Group .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Config Key Groups and generate a metadata report .PARAMETER OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Invoke-D365GenerateReportConfigKeyGroup This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> function Invoke-D365GenerateReportConfigKeyGroup { [CmdletBinding()] param ( [string] $OutputPath = $Script:DefaultTempPath, [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) begin { $outputFile = Join-Path -Path $OutputPath -ChildPath "ConfigKeyGroups.xlsx" Import-GenerateReportAssemblies $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $providerConfig.XppMetadataPath = $PackageDirectory $providerConfig.MetadataPath = $PackageDirectory $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig) $productVersionDetails = Get-D365ProductInformation if (-not $productVersionDetails.ApplicationBuildVersion) { $version = $productVersionDetails.ApplicationVersion } else { $version = $productVersionDetails.ApplicationBuildVersion } } process { if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Getting all Configuration Key Groups via the metadata provider." $configKeyModelInfos = $metadataProvider.ConfigurationKeyGroups.GetPrimaryKeysWithModelInfo() $configKeyGroups = New-Object System.Collections.Generic.List[object] foreach ($tuple in $configKeyModelInfos) { $elementName = $tuple.Item1 Write-PSFMessage -Level Verbose -Message "Working on: $elementName (ConfigurationKeyGroup)" -Target $elementName $modelInfoNames = $tuple.Item2 | Select-Object -ExpandProperty Name # convert list of ModelInfo objects to list of Names $modelNames = [string]::Join("; ", $modelInfoNames); $element = $metadataProvider.ConfigurationKeyGroups.Read($elementName) $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair Name = $element.Name Models = $modelNames LicenseCode = $element.LicenseCode ParentKeyGroup = $element.ParentKeyGroup ConfigKeys = $element.ConfigurationKeys Enabled = $element.Enabled LabelID = $element.Label Label = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label) } $configKeyGroups.Add($outItems) } $reportName = "ConfigKeyGroups" $sheetName = "$reportName`_$version" $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length)) $configKeyGroups | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName [PSCustomObject]@{ Report = $reportName File = $outputFile Filename = (Split-Path $outputFile -Leaf) } } } ================================================ FILE: d365fo.tools/functions/invoke-d365generatereportdataentity.ps1 ================================================  <# .SYNOPSIS Generate Report for Data Entity .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Data Entities and generate a metadata report .PARAMETER OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Invoke-D365GenerateReportDataEntity This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> function Invoke-D365GenerateReportDataEntity { [CmdletBinding()] param ( [string] $OutputPath = $Script:DefaultTempPath, [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) begin { $outputFile = Join-Path -Path $OutputPath -ChildPath "DataEntities.xlsx" Import-GenerateReportAssemblies $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $providerConfig.XppMetadataPath = $PackageDirectory $providerConfig.MetadataPath = $PackageDirectory $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig) $productVersionDetails = Get-D365ProductInformation if (-not $productVersionDetails.ApplicationBuildVersion) { $version = $productVersionDetails.ApplicationVersion } else { $version = $productVersionDetails.ApplicationBuildVersion } } process { if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Getting all Data Entities via the metadata provider." $dataEntityModelInfos = $metadataProvider.DataEntityViews.GetPrimaryKeysWithModelInfo() $dataEntities = New-Object System.Collections.Generic.List[object] foreach ($tuple in $dataEntityModelInfos) { $elementName = $tuple.Item1 Write-PSFMessage -Level Verbose -Message "Working on: $elementName (DataEntity)" -Target $elementName $element = $metadataProvider.DataEntityViews.Read($elementName) #filter out system fields $fields = @() foreach ($j in $element.Fields) { if ($j -notlike "AX_*") { $fields += $j } } $outItems = [PsCustomObject][ordered] @{ # create a hash table of the name/value pair Name = $element.Name DataSource = [string]::Join(", ", $element.ViewMetadata.DataSources) Public = $element.IsPublic ODataAccessible = $element.IsPublic PublicCollectionName = $element.PublicCollectionName StagingTable = $element.DataManagementStagingTable EntityCategory = $element.EntityCategory TableGroup = $element.TableGroup Fields = [string]::Join(", ", $fields) DataManagementEnabled = $element.DataManagementEnabled } $dataEntities.add($outItems) } $reportName = "DataEntities" $sheetName = "$reportName`_$version" $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length)) $dataEntities | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName [PSCustomObject]@{ Report = $reportName File = $outputFile Filename = (Split-Path $outputFile -Leaf) } } } ================================================ FILE: d365fo.tools/functions/invoke-d365generatereportdataentityfield.ps1 ================================================  <# .SYNOPSIS Generate Report for Data Entity with fields .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Data Entities with their fields and generate a metadata report .PARAMETER OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Invoke-D365GenerateReportDataEntityField This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> function Invoke-D365GenerateReportDataEntityField { [CmdletBinding()] param ( [string] $OutputPath = $Script:DefaultTempPath, [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) begin { $outputFile = Join-Path -Path $OutputPath -ChildPath "DataEntityFields.xlsx" Write-PSFMessage -Level Verbose -Message "Getting all Data Entities with Fields from the internal functions." $dataEntities = Get-AxDataEntities -BinDir $BinDir -PackageDirectory $PackageDirectory } process { if (Test-PSFFunctionInterrupt) { return } $reportName = "DataEntityFields" $sheetName = "$reportName`_$version" $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length)) $dataEntities | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName [PSCustomObject]@{ Report = $reportName File = $outputFile Filename = (Split-Path $outputFile -Leaf) } } } ================================================ FILE: d365fo.tools/functions/invoke-d365generatereportkpi.ps1 ================================================  <# .SYNOPSIS Generate Report for KPI .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all KPIs and generate a metadata report .PARAMETER OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Invoke-D365GenerateReportKpi This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> function Invoke-D365GenerateReportKpi { [CmdletBinding()] param ( [string] $OutputPath = $Script:DefaultTempPath, [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) begin { $outputFile = Join-Path -Path $OutputPath -ChildPath "KPIs.xlsx" Import-GenerateReportAssemblies $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $providerConfig.XppMetadataPath = $PackageDirectory $providerConfig.MetadataPath = $PackageDirectory $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig) $productVersionDetails = Get-D365ProductInformation if (-not $productVersionDetails.ApplicationBuildVersion) { $version = $productVersionDetails.ApplicationVersion } else { $version = $productVersionDetails.ApplicationBuildVersion } } process { if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Getting all KPIs via the metadata provider." $KPIModelInfos = $metadataProvider.KPIs.GetPrimaryKeysWithModelInfo() $KPIs = New-Object System.Collections.Generic.List[object] foreach ($tuple in $KPIModelInfos) { $elementName = $tuple.Item1 Write-PSFMessage -Level Verbose -Message "Working on: $elementName (KPI)" -Target $elementName $element = $metadataProvider.KPIs.Read($elementName) if ($element.Name -eq "FMRevenue") { $calcMeasure = $element.Value.Measure $calcMeasureGroup = $element.Value.MeasureGroup } else { $calcMeasure = $element.Goal.Measure $calcMeasureGroup = $element.Goal.MeasureGroup } $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair Name = $element.Name Label = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label) Measurement = $element.Measurement ValueType = $element.Value.ValueType GoalType = $element.Goal.GoalType Value = $element.goal.Value CalculatedMeasure = $calcMeasure CalculatedMeasureGroup = $calcMeasureGroup FormExposed = "" WorkspaceExposed = "" } $KPIs.Add($outItems) } $reportName = "KPIs" $sheetName = "$reportName`_$version" $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length)) $KPIs | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName [PSCustomObject]@{ Report = $reportName File = $outputFile Filename = (Split-Path $outputFile -Leaf) } } } ================================================ FILE: d365fo.tools/functions/invoke-d365generatereportlicensecode.ps1 ================================================  <# .SYNOPSIS Generate Report for License Code .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all License Codes and generate a metadata report .PARAMETER OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Invoke-D365GenerateReportLicenseCode This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> function Invoke-D365GenerateReportLicenseCode { [CmdletBinding()] param ( [string] $OutputPath = $Script:DefaultTempPath, [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) begin { $outputFile = Join-Path -Path $OutputPath -ChildPath "LicenseCodes.xlsx" Import-GenerateReportAssemblies $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $providerConfig.XppMetadataPath = $PackageDirectory $providerConfig.MetadataPath = $PackageDirectory $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig) $productVersionDetails = Get-D365ProductInformation if (-not $productVersionDetails.ApplicationBuildVersion) { $version = $productVersionDetails.ApplicationVersion } else { $version = $productVersionDetails.ApplicationBuildVersion } } process { if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Getting all License Codes via the metadata provider." $licenseCodeModelInfos = $metadataProvider.LicenseCodes.GetPrimaryKeysWithModelInfo() $licenseCodes = New-Object System.Collections.Generic.List[object] foreach ($tuple in $licenseCodeModelInfos) { $elementName = $tuple.Item1 Write-PSFMessage -Level Verbose -Message "Working on: $elementName (LicenseCode)" -Target $elementName $modelInfoNames = $tuple.Item2 | Select-Object -ExpandProperty Name # convert list of ModelInfo objects to list of Names $modelNames = [string]::Join("; ", $modelInfoNames); $element = $metadataProvider.LicenseCodes.Read($elementName) $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair Name = $element.Name Models = $modelNames Package = $element.Package LabelID = $element.Label Label = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label) } $licenseCodes.Add($outItems) } $reportName = "LicenseCodes" $sheetName = "$reportName`_$version" $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length)) $licenseCodes | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName [PSCustomObject]@{ Report = $reportName File = $outputFile Filename = (Split-Path $outputFile -Leaf) } } } ================================================ FILE: d365fo.tools/functions/invoke-d365generatereportmenuitem.ps1 ================================================  <# .SYNOPSIS Generate Report for Menu Item .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all types of Menu Items and generate a metadata report .PARAMETER OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Invoke-D365GenerateReportMenuItem This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> function Invoke-D365GenerateReportMenuItem { [CmdletBinding()] param ( [string] $OutputPath = $Script:DefaultTempPath, [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) begin { $outputFile = Join-Path -Path $OutputPath -ChildPath "MenuItems.xlsx" Import-GenerateReportAssemblies $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $providerConfig.XppMetadataPath = $PackageDirectory $providerConfig.MetadataPath = $PackageDirectory $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig) $productVersionDetails = Get-D365ProductInformation if (-not $productVersionDetails.ApplicationBuildVersion) { $version = $productVersionDetails.ApplicationVersion } else { $version = $productVersionDetails.ApplicationBuildVersion } } process { if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Getting all Menu Items (Display) via the metadata provider." $displayMenuItemModelInfos = $metadataProvider.MenuItemDisplays.GetPrimaryKeysWithModelInfo() $menuItems = New-Object System.Collections.Generic.List[object] foreach ($tuple in $displayMenuItemModelInfos) { $elementName = $tuple.Item1 Write-PSFMessage -Level Verbose -Message "Working on: $elementName (MenuItemDisplay)" -Target $elementName $modelInfoNames = $tuple.Item2 | Select-Object -ExpandProperty Name # convert list of ModelInfo objects to list of Names $modelNames = [string]::Join("; ", $modelInfoNames); $element = $metadataProvider.MenuItemDisplays.Read($elementName) $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair Name = $element.Name MenuItemType = "Display" Models = $modelNames ObjectType = $element.ObjectType Object = $element.Object ConfigKey = $element.ConfigurationKey Enabled = $element.Enabled LabelID = $element.Label Label = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label) } $menuItems.Add($outItems) } Write-PSFMessage -Level Verbose -Message "Getting all Menu Items (Action) via the metadata provider." $actionMenuItemModelInfos = $metadataProvider.MenuItemActions.GetPrimaryKeysWithModelInfo() foreach ($tuple in $actionMenuItemModelInfos) { $elementName = $tuple.Item1 Write-PSFMessage -Level Verbose -Message "Working on: $elementName (MenuItemAction)" -Target $elementName $modelInfoNames = $tuple.Item2 | Select-Object -ExpandProperty Name # convert list of ModelInfo objects to list of Names $modelNames = [string]::Join("; ", $modelInfoNames); $element = $metadataProvider.MenuItemActions.Read($elementName) $outItems = New-Object PSObject -Property @{ # create a hash table of the name/value pair Name = $element.Name MenuItemType = "Action" Models = $modelNames ObjectType = $element.ObjectType Object = $element.Object ConfigKey = $element.ConfigurationKey Enabled = $element.Enabled LabelID = $element.Label Label = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label) } $menuItems.Add($outItems) } Write-PSFMessage -Level Verbose -Message "Getting all Menu Items (Output) via the metadata provider." $outputMenuItemModelInfos = $metadataProvider.MenuItemOutputs.GetPrimaryKeysWithModelInfo() foreach ($tuple in $outputMenuItemModelInfos) { $elementName = $tuple.Item1 Write-PSFMessage -Level Verbose -Message "Working on: $elementName (MenuItemOutput)" -Target $elementName $modelInfoNames = $tuple.Item2 | Select-Object -ExpandProperty Name # convert list of ModelInfo objects to list of Names $modelNames = [string]::Join("; ", $modelInfoNames); $element = $metadataProvider.MenuItemOutputs.Read($elementName) $outItems = New-Object PSObject -Property @{ # create a hash table of the name/value pair Name = $element.Name MenuItemType = "Output" Models = $modelNames ObjectType = $element.ObjectType Object = $element.Object ConfigKey = $element.ConfigurationKey Enabled = $element.Enabled LabelID = $element.Label Label = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label) } $menuItems.Add($outItems) } $reportName = "MenuItems" $sheetName = "$reportName`_$version" $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length)) $menuItems | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName [PSCustomObject]@{ Report = $reportName File = $outputFile Filename = (Split-Path $outputFile -Leaf) } } } ================================================ FILE: d365fo.tools/functions/invoke-d365generatereports.ps1 ================================================  <# .SYNOPSIS Generate Report for all related objects .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all related objects and generate a metadata report for each .PARAMETER OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Invoke-D365GenerateReports This will generate a report for each related object. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) #> function Invoke-D365GenerateReports { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param ( [string] $OutputPath = $Script:DefaultTempPath, [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) process { Invoke-TimeSignal -Start $reports = @() $reports += Invoke-D365GenerateReportAggregateDataEntity @PSBoundParameters $reports += Invoke-D365GenerateReportAggregateMeasure @PSBoundParameters $reports += Invoke-D365GenerateReportConfigKey @PSBoundParameters $reports += Invoke-D365GenerateReportConfigKeyGroup @PSBoundParameters $reports += Invoke-D365GenerateReportDataEntity @PSBoundParameters $reports += Invoke-D365GenerateReportDataEntityField @PSBoundParameters $reports += Invoke-D365GenerateReportKpi @PSBoundParameters $reports += Invoke-D365GenerateReportLicenseCode @PSBoundParameters $reports += Invoke-D365GenerateReportMenuItem @PSBoundParameters $reports += Invoke-D365GenerateReportSsrs @PSBoundParameters $reports += Invoke-D365GenerateReportTable @PSBoundParameters $reports += Invoke-D365GenerateReportWorkflowType @PSBoundParameters Invoke-TimeSignal -End $reports } } ================================================ FILE: d365fo.tools/functions/invoke-d365generatereportssrs.ps1 ================================================  <# .SYNOPSIS Generate Report for SSRS Report .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all SSRS Reports and generate a metadata report .PARAMETER OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Invoke-D365GenerateReportSsrs This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> function Invoke-D365GenerateReportSsrs { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param ( [string] $OutputPath = $Script:DefaultTempPath, [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) begin { $outputFile = Join-Path -Path $OutputPath -ChildPath "SSRSReports.xlsx" Import-GenerateReportAssemblies $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $providerConfig.XppMetadataPath = $PackageDirectory $providerConfig.MetadataPath = $PackageDirectory $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig) $productVersionDetails = Get-D365ProductInformation if (-not $productVersionDetails.ApplicationBuildVersion) { $version = $productVersionDetails.ApplicationVersion } else { $version = $productVersionDetails.ApplicationBuildVersion } } process { if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Getting all SSRS Reports via the metadata provider." $reportsModelInfos = $metadataProvider.Reports.GetPrimaryKeysWithModelInfo() #array of the names of all the reports that use Print Management (used PrintMgmtReportFormat table from Application Explorer) $printMgmtReports = @("SalesInvoice", "SalesConfirm", "SalesPackingSlip", "WMSPickingList_OrderPick", "FreeTestInvoice", "SalesQuotationConfirmation", "SalesQuotation", "VendInvoiceDocument", "PurchPackingSlip", "PurchReceiptsList", "PurchPurchaseOrder", "ProjInvoice", "PurchRFQFormLetter_Send", "CustInterestNote", "CustCOllectionJour", "CustAccountStatementExt", "AgreementConfirmation", "PSAQuotations", "PSAProjInvoice", "PSAContractLineInvoice", "PSAManageInvoice", "PSAManageInvoiceBR", "PSACustRetentionReleaseInvoice") $reports = New-Object System.Collections.Generic.List[object] foreach ($tuple in $reportsModelInfos) { $elementName = $tuple.Item1 Write-PSFMessage -Level Verbose -Message "Working on: $elementName (SsrsReport)" -Target $elementName $element = $metadataProvider.Reports.Read($elementName) $printMgmt = $($printMgmtReports -contains $element.Name) foreach ($i in $element.DataSets) { #filter out system fields $fields = @() foreach ($j in $i.Fields) { if ($j -notlike "AX_*") { $fields += $j } } $filters = @() #filter out system parameters foreach ($k in $i.Parameters) { if ($k -notlike "AX_*") { $filters += $k } } $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair Name = $element.Name DataSet = $i.Name Filters = [string]::Join(", ", $filters) Fields = [string]::Join(", ", $fields) PrintMgmt = $printMgmt } $reports.Add($outItems) } } $reportName = "SSRSReports" $sheetName = "$reportName`_$version" $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length)) $reports | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName [PSCustomObject]@{ Report = $reportName File = $outputFile Filename = (Split-Path $outputFile -Leaf) } } } ================================================ FILE: d365fo.tools/functions/invoke-d365generatereporttable.ps1 ================================================  <# .SYNOPSIS Generate Report for Table .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Tables and generate a metadata report .PARAMETER OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Invoke-D365GenerateReportTable This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> function Invoke-D365GenerateReportTable { [CmdletBinding()] param ( [string] $OutputPath = $Script:DefaultTempPath, [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) begin { $outputFile = Join-Path -Path $OutputPath -ChildPath "Tables.xlsx" Import-GenerateReportAssemblies $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $providerConfig.XppMetadataPath = $PackageDirectory $providerConfig.MetadataPath = $PackageDirectory $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig) $productVersionDetails = Get-D365ProductInformation if (-not $productVersionDetails.ApplicationBuildVersion) { $version = $productVersionDetails.ApplicationVersion } else { $version = $productVersionDetails.ApplicationBuildVersion } 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" } process { if (Test-PSFFunctionInterrupt) { return } $dataEntities = Get-AxDataEntities -BinDir $BinDir -PackageDirectory $PackageDirectory $forms = Get-AxForms -BinDir $BinDir -PackageDirectory $PackageDirectory $views = Get-AxViews -BinDir $BinDir -PackageDirectory $PackageDirectory Write-PSFMessage -Level Verbose -Message "Getting all SSRS Reports via the metadata provider." $tablesModelInfos = $metadataProvider.Tables.GetPrimaryKeysWithModelInfo() #declare variables $entityOrView $crossCompany = "" $tables = New-Object System.Collections.Generic.List[object] foreach ($tuple in $tablesModelInfos) { $elementName = $tuple.Item1 Write-PSFMessage -Level Verbose -Message "Working on: $elementName (Table)" -Target $elementName $element = $metadataProvider.Tables.Read($elementName) #check if table is used in an entity $entityMatch = "No" foreach ($i in $dataEntities) { if ($i.DataSource) { if ($i.DataSource.StartsWith($element.Name + " [")) { $entityMatch = "Yes" } } } #check if table is used in a view $viewMatch = "No" foreach ($i in $views) { foreach ($k in $i.DataSources) { if ($element.Name -eq $k.Name) { $viewMatch = "Yes" } } } if ($viewMatch -eq "Yes" -or $entityMatch -eq "Yes") { $entityOrView = "Yes" } else { $entityOrView = "No" } #check if form's data source is the table and then taking CrossCompanyAutoQuery property foreach ($i in $forms) { foreach ($k in $i.DataSources) { if ($k.Name -eq $element.Name) { $crossCompany = $k.CrossCompanyAutoQuery if ($crossCompany -eq "") { $crossCompany = "No" } } } } $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair Name = $element.Name TableGroup = $element.TableGroup CrossCompany = $crossCompany SystemTable = $element.SystemTable Indexes = [string]::Join(", ", $element.Indexes) EntityOrView = $entityOrView } $tables.Add($outItems) } $reportName = "Tables" $sheetName = "$reportName`_$version" $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length)) $tables | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName [PSCustomObject]@{ Report = $reportName File = $outputFile Filename = (Split-Path $outputFile -Leaf) } } } ================================================ FILE: d365fo.tools/functions/invoke-d365generatereportworkflowtype.ps1 ================================================  <# .SYNOPSIS Generate Report for Workflow Type .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Workflow Types and generate a metadata report .PARAMETER OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Invoke-D365GenerateReportWorkflowType This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> function Invoke-D365GenerateReportWorkflowType { [CmdletBinding()] param ( [string] $OutputPath = $Script:DefaultTempPath, [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) begin { $outputFile = Join-Path -Path $OutputPath -ChildPath "WorkflowTypes.xlsx" Import-GenerateReportAssemblies $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $providerConfig.XppMetadataPath = $PackageDirectory $providerConfig.MetadataPath = $PackageDirectory $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig) $productVersionDetails = Get-D365ProductInformation if (-not $productVersionDetails.ApplicationBuildVersion) { $version = $productVersionDetails.ApplicationVersion } else { $version = $productVersionDetails.ApplicationBuildVersion } } process { if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Getting all SSRS Reports via the metadata provider." $workflowTypesModelInfos = $metadataProvider.WorkflowTemplates.GetPrimaryKeysWithModelInfo() $workflowTypes = New-Object System.Collections.Generic.List[object] foreach ($tuple in $workflowTypesModelInfos) { $elementName = $tuple.Item1 Write-PSFMessage -Level Verbose -Message "Working on: $elementName (WorkflowType)" -Target $elementName $element = $metadataProvider.WorkflowTemplates.Read($elementName) foreach ($supportedElement in $element.SupportedElements) { $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair Name = $element.Name Label = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.Label) HelpText = [Microsoft.Dynamics.Ax.Xpp.LabelHelper]::GetLabel($element.HelpText) AssociationType = $element.AssociationType Category = $element.Category Participant = $supportedElement.Name Role = $supportedElement.Type } } $workflowTypes.Add($outItems) } $reportName = "WorkflowTypes" $sheetName = "$reportName`_$version" $sheetName = $sheetName.subString(0, [System.Math]::Min(31, $sheetName.Length)) $workflowTypes | Sort-Object Name | Export-Excel -Path $outputFile -WorksheetName $sheetName -ClearSheet -AutoSize -TableName $reportName [PSCustomObject]@{ Report = $reportName File = $outputFile Filename = (Split-Path $outputFile -Leaf) } } } ================================================ FILE: d365fo.tools/functions/invoke-d365installazcopy.ps1 ================================================  <# .SYNOPSIS Download AzCopy.exe to your machine .DESCRIPTION Download and extract the AzCopy.exe to your machine .PARAMETER Url Url/Uri to where the latest AzCopy download is located The default value is for v10 as of writing .PARAMETER Path Path to where you want the AzCopy to be extracted to Default value is: "C:\temp\d365fo.tools\AzCopy\AzCopy.exe" .EXAMPLE PS C:\> Invoke-D365InstallAzCopy -Path "C:\temp\d365fo.tools\AzCopy\AzCopy.exe" This will update the path for the AzCopy.exe in the modules configuration .NOTES Author: Mötz Jensen (@Splaxi) #> function Invoke-D365InstallAzCopy { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] [OutputType()] param ( [string] $Url = "https://aka.ms/downloadazcopy-v10-windows", [string] $Path = "C:\temp\d365fo.tools\AzCopy\AzCopy.exe" ) $azCopyFolder = Split-Path $Path -Parent $downloadPath = Join-Path -Path $azCopyFolder -ChildPath "AzCopy.zip" if (-not (Test-PathExists -Path $azCopyFolder -Type Container -Create)) { return } if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Downloading AzCopy.zip from the internet. $($Url)" -Target $Url (New-Object System.Net.WebClient).DownloadFile($Url, $downloadPath) if (-not (Test-PathExists -Path $downloadPath -Type Leaf)) { return } Unblock-File -Path $downloadPath $tempExtractPath = Join-Path -Path $azCopyFolder -ChildPath "Temp" Expand-Archive -Path $downloadPath -DestinationPath $tempExtractPath -Force $null = (Get-Item "$tempExtractPath\*\azcopy.exe").CopyTo($Path, $true) $tempExtractPath | Remove-Item -Force -Recurse $downloadPath | Remove-Item -Force -Recurse Set-D365AzCopyPath -Path $Path } ================================================ FILE: d365fo.tools/functions/invoke-d365installlicense.ps1 ================================================  <# .SYNOPSIS Install a license for a 3. party solution .DESCRIPTION Install a license for a 3. party solution using the builtin "Microsoft.Dynamics.AX.Deployment.Setup.exe" executable .PARAMETER Path Path to the license file .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .EXAMPLE PS C:\> Invoke-D365InstallLicense -Path c:\temp\d365fo.tools\license.txt 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. .EXAMPLE PS C:\> Invoke-D365InstallLicense -Path c:\temp\d365fo.tools\license.txt -ShowOriginalProgress 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. The output from the installation process will be written to the console / host. .NOTES Tags: License, Install, ISV, 3. Party, Servicing Author: Mötz Jensen (@splaxi) #> function Invoke-D365InstallLicense { [CmdletBinding()] param ( [Parameter(Mandatory = $True)] [Alias('File')] [string] $Path, [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword, [string] $MetaDataDir = "$Script:MetaDataDir", [string] $BinDir = "$Script:BinDir", [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\InstallLicense"), [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) $executable = Join-Path -Path $BinDir -ChildPath "bin\Microsoft.Dynamics.AX.Deployment.Setup.exe" if (-not (Test-PathExists -Path $MetaDataDir,$BinDir -Type Container)) {return} if (-not (Test-PathExists -Path $Path,$executable -Type Leaf)) {return} Invoke-TimeSignal -Start $params = @("-isemulated", "true", "-sqluser", "$SqlUser", "-sqlpwd", "$SqlPwd", "-sqlserver", "$DatabaseServer", "-sqldatabase", "$DatabaseName", "-metadatadir", "$MetaDataDir", "-bindir", "$BinDir", "-setupmode", "importlicensefile", "-licensefilename", "`"$Path`"") Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/invoke-d365installnuget.ps1 ================================================  <# .SYNOPSIS Download nuget.exe to your machine .DESCRIPTION Download the nuget.exe to your machine By default it will download the latest version .PARAMETER Path Path to where you want the nuget.exe to be downloaded to Default value is: "C:\temp\d365fo.tools\nuget\nuget.exe" .PARAMETER Url Url/Uri to where the latest nuget download is located The default value is "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" .EXAMPLE PS C:\> Invoke-D365InstallNuget This will download the latest version of nuget. The install path is identified by the default value: "C:\temp\d365fo.tools\nuget\nuget.exe". .NOTES Author: Mötz Jensen (@Splaxi) #> function Invoke-D365InstallNuget { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] [OutputType()] param ( [string] $Path = "C:\temp\d365fo.tools\nuget", [string] $Url = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" ) $downloadPath = Join-Path -Path $Path -ChildPath "nuget.exe" if (-not (Test-PathExists -Path $Path -Type Container -Create)) { return } if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Downloading nuget.exe from the internet. $($Url)" -Target $Url (New-Object System.Net.WebClient).DownloadFile($Url, $downloadPath) if (-not (Test-PathExists -Path $downloadPath -Type Leaf)) { return } Unblock-File -Path $downloadPath Set-D365NugetPath -Path $downloadPath } ================================================ FILE: d365fo.tools/functions/invoke-d365installsqlpackage.ps1 ================================================  <# .SYNOPSIS Download SqlPackage.exe to your machine .DESCRIPTION Download and extract SqlPackage.exe to your machine. .PARAMETER Path Path to where you want the SqlPackage to be extracted to Default value is: "C:\temp\d365fo.tools\SqlPackage\SqlPackage.exe" .PARAMETER Latest Overrides the Url parameter and uses the latest download URL provided by the evergreen link https://aka.ms/sqlpackage-windows .PARAMETER Url Url/Uri to where the SqlPackage download is located The default value is for version 162.2.111.2 as of writing. Further discussion can be found here: https://github.com/d365collaborative/d365fo.tools/discussions/816 .EXAMPLE PS C:\> Invoke-D365InstallSqlPackage This will download and extract SqlPackage.exe. It will use the default value for the Path parameter, for where to save the SqlPackage.exe. It will update the path for the SqlPackage.exe in configuration. .EXAMPLE PS C:\> Invoke-D365InstallSqlPackage -Path "C:\temp\SqlPackage" This will download and extract SqlPackage.exe. It will save the SqlPackage.exe to "C:\temp\SqlPackage". It will update the path for the SqlPackage.exe in configuration. .EXAMPLE PS C:\> Invoke-D365InstallSqlPackage -Latest This will download and extract the latest SqlPackage.exe. It will use https://aka.ms/sqlpackage-windows as the download URL. It will update the path for the SqlPackage.exe in configuration. .EXAMPLE PS C:\> Invoke-D365InstallSqlPackage -Url "https://go.microsoft.com/fwlink/?linkid=3030303" This will download and extract SqlPackage.exe. It will rely on the Url parameter to base the download on. It will use the "https://go.microsoft.com/fwlink/?linkid=3030303" as value for the Url parameter. It will update the path for the SqlPackage.exe in configuration. .NOTES Author: Mötz Jensen (@Splaxi) Author: Florian Hopfner (@FH-Inway) #> function Invoke-D365InstallSqlPackage { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding(DefaultParameterSetName = 'ImportUrl')] [OutputType()] param ( [Parameter(ParameterSetName = 'ImportUrl')] [Parameter(ParameterSetName = 'ImportLatest')] [string] $Path = "C:\temp\d365fo.tools\SqlPackage", [Parameter(ParameterSetName = 'ImportLatest')] [switch] $Latest, [Parameter(ParameterSetName = 'ImportUrl')] [string] $Url = "https://go.microsoft.com/fwlink/?linkid=2261576" ) if ($Latest) { $Url = "https://aka.ms/sqlpackage-windows" } $sqlPackageFolder = $Path $downloadPath = Join-Path -Path $sqlPackageFolder -ChildPath "SqlPackage.zip" if (-not (Test-PathExists -Path $sqlPackageFolder -Type Container -Create)) { return } if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Downloading SqlPackage.zip from the internet. $($Url)" -Target $Url (New-Object System.Net.WebClient).DownloadFile($Url, $downloadPath) if (-not (Test-PathExists -Path $downloadPath -Type Leaf)) { return } Unblock-File -Path $downloadPath $tempExtractPath = Join-Path -Path $sqlPackageFolder -ChildPath "Temp" Expand-Archive -Path $downloadPath -DestinationPath $tempExtractPath -Force Get-ChildItem -Path $tempExtractPath | Move-Item -Destination { $_.Directory.Parent.FullName } -Force $tempExtractPath | Remove-Item -Force -Recurse $downloadPath | Remove-Item -Force -Recurse $SqlPackagePath = Join-Path -Path $Path -ChildPath "SqlPackage.exe" Set-D365SqlPackagePath -Path $SqlPackagePath $result = Invoke-Process -Path $SqlPackagePath -Params "/Version" $version = $result.stdout -replace "`r`n", "" Write-PSFMessage -Level Host -Message "SqlPackage.exe version $version has been downloaded and extracted to $SqlPackagePath" } ================================================ FILE: d365fo.tools/functions/invoke-d365lcsapirefreshtoken.ps1 ================================================  <# .SYNOPSIS Refresh the token for lcs communication .DESCRIPTION Invoke the refresh logic that refreshes the token object based on the ClientId and RefreshToken .PARAMETER ClientId The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal .PARAMETER RefreshToken The Refresh Token that you want to use for the authentication process .PARAMETER InputObject The entire object that you received from the Get-D365LcsApiToken command, which contains the needed RefreshToken .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Invoke-D365LcsApiRefreshToken -ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" -RefreshToken "Tsdljfasfe2j32324" This will refresh an OAuth 2.0 access token, and obtain a (new) valid OAuth 2.0 access token from Azure Active Directory. The ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" is used in the OAuth 2.0 "Refresh Token" Grant Flow to authenticate. The RefreshToken "Tsdljfasfe2j32324" is used to prove to Azure Active Directoy that we are allowed to obtain a new valid Access Token. .EXAMPLE PS C:\> $temp = Get-D365LcsApiToken -LcsApiUri "https://lcsapi.eu.lcs.dynamics.com" -ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" -Username "serviceaccount@domain.com" -Password "TopSecretPassword" PS C:\> $temp = Invoke-D365LcsApiRefreshToken -ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" -InputObject $temp This will refresh an OAuth 2.0 access token, and obtain a (new) valid OAuth 2.0 access token from Azure Active Directory. This will obtain a new token object from the Get-D365LcsApiToken cmdlet and store it in $temp. Then it will pass $temp to the Invoke-D365LcsApiRefreshToken along with the ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929". The new token object will be save into $temp. .EXAMPLE PS C:\> Get-D365LcsApiConfig | Invoke-D365LcsApiRefreshToken | Set-D365LcsApiConfig This will refresh an OAuth 2.0 access token, and obtain a (new) valid OAuth 2.0 access token from Azure Active Directory. This will fetch the current LCS API details from Get-D365LcsApiConfig. The output from Get-D365LcsApiConfig is piped directly to Invoke-D365LcsApiRefreshToken, which will fetch a new token object. The new token object is piped directly into Set-D365LcsApiConfig, which will save the needed details into the configuration store. .LINK Get-D365LcsApiConfig .LINK Get-D365LcsApiToken .LINK Get-D365LcsAssetValidationStatus .LINK Get-D365LcsDeploymentStatus .LINK Invoke-D365LcsDeployment .LINK Invoke-D365LcsUpload .LINK Set-D365LcsApiConfig .NOTES Tags: LCS, API, Token, BearerToken Author: Mötz Jensen (@Splaxi) #> function Invoke-D365LcsApiRefreshToken { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseProcessBlockForPipelineCommand", "")] [CmdletBinding()] [OutputType()] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Simple")] [Parameter(Mandatory = $true, ParameterSetName = "Object")] [string] $ClientId, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Simple")] [Alias('refresh_token')] [Alias('Token')] [string] $RefreshToken, [Parameter(Mandatory = $false, ParameterSetName = "Object")] [PSCustomObject] $InputObject, [switch] $EnableException ) if ($PsCmdlet.ParameterSetName -eq "Simple") { Invoke-RefreshToken -AuthProviderUri $Script:AADOAuthEndpoint @PSBoundParameters } else { Invoke-RefreshToken -AuthProviderUri $Script:AADOAuthEndpoint -ClientId $ClientId -RefreshToken $InputObject.refresh_token } } ================================================ FILE: d365fo.tools/functions/invoke-d365lcsdatabaseexport.ps1 ================================================  <# .SYNOPSIS Start a database export from an environment .DESCRIPTION Start a database export from an environment from a LCS project .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER SourceEnvironmentId The unique id of the environment that you want to use as the source for the database export The Id can be located inside the LCS portal .PARAMETER BackupName Name of the backup file when it is being exported from the environment The file shouldn't contain any extension at all, just the desired file name .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER SkipInitialStatusFetch Instruct the cmdlet to skip the first fetch of the database refresh status Useful when you have a large script that handles this status validation and you don't want to spend time with this cmdlet 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. Setting this parameter (activate it), will affect the number of output objects. If you skip, only the first response object outputted. .PARAMETER FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Invoke-D365LcsDatabaseExport -ProjectId 123456789 -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -BackupName "BackupViaApi" -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will start the database export from the Source environment. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The backup name is identified by the BackupName "BackupViaApi", which instructs the API to save the backup with that filename. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .EXAMPLE PS C:\> Invoke-D365LcsDatabaseExport -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -BackupName "BackupViaApi" This will start the database export from the Source environment. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The backup name is identified by the BackupName "BackupViaApi", which instructs the API to save the backup with that filename. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> $databaseExport = Invoke-D365LcsDatabaseExport -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -BackupName "BackupViaApi" -SkipInitialStatusFetch PS C:\> $databaseExport | Get-D365LcsDatabaseOperationStatus -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e9" -SleepInSeconds 60 This will start the database export from the Source environment. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The backup name is identified by the BackupName "BackupViaApi", which instructs the API to save the backup with that filename. It will skip the first database operation status fetch and only output the details from starting the export. 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. Will pipe the $databaseExport variable to the Get-D365LcsDatabaseOperationStatus cmdlet and get the status from the database export job. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Invoke-D365LcsDatabaseExport -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -BackupName "BackupViaApi" -SkipInitialStatusFetch This will start the database export from the Source environment. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The backup name is identified by the BackupName "BackupViaApi", which instructs the API to save the backup with that filename. It will skip the first database operation status fetch and only output the details from starting the export. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Invoke-D365LcsDatabaseExport -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -BackupName "BackupViaApi" -RetryTimeout "00:01:00" This will start the database export from the Source environment, and allow for the cmdlet to retry for no more than 1 minute. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The backup name is identified by the BackupName "BackupViaApi", which instructs the API to save the backup with that filename. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .LINK Get-D365LcsDatabaseOperationStatus .LINK Get-D365LcsApiConfig .LINK Get-D365LcsApiToken .LINK Get-D365LcsAssetValidationStatus .LINK Get-D365LcsDeploymentStatus .LINK Invoke-D365LcsApiRefreshToken .LINK Invoke-D365LcsUpload .LINK Set-D365LcsApiConfig .NOTES 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). 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. 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. Setting the SkipInitialStatusFetch parameter (activate it), will affect the number of output objects. If you skip, only the first response object outputted. 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. Tags: Environment, Config, Configuration, LCS, Database backup, Api, Backup, Bacpac Author: Mötz Jensen (@Splaxi) #> function Invoke-D365LcsDatabaseExport { [CmdletBinding()] [OutputType()] param( [int] $ProjectId = $Script:LcsApiProjectId, [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [Parameter(Mandatory = $true)] [string] $SourceEnvironmentId, [Parameter(Mandatory = $true)] [string] $BackupName, [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [switch] $SkipInitialStatusFetch, [switch] $FailOnErrorMessage, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) Invoke-TimeSignal -Start if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } $exportJob = Start-LcsDatabaseExportV2 -ProjectId $ProjectId -BearerToken $BearerToken -SourceEnvironmentId $SourceEnvironmentId -BackupName $BackupName -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout if (Test-PSFFunctionInterrupt) { return } if ($FailOnErrorMessage -and $exportJob.ErrorMessage) { $messageString = "The request against LCS succeeded, but the response was an error message for the operation: $($exportJob.ErrorMessage)." $errorMessagePayload = "`r`n$($exportJob | ConvertTo-Json)" Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $exportJob Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $exportJob } $temp = [PSCustomObject]@{ EnvironmentId = "$SourceEnvironmentId"; OperationStatus = "NotStarted"; } #Hack to silence the PSScriptAnalyzer $temp | Out-Null $exportJob | Select-PSFObject *, "OperationActivityId as ActivityId", "EnvironmentId from temp as EnvironmentId", "OperationStatus from temp as OperationStatus" -TypeName "D365FO.TOOLS.LCS.Database.Operation.Status" if (-not $SkipInitialStatusFetch) { Get-D365LcsDatabaseOperationStatus -ProjectId $ProjectId -BearerToken $BearerToken -OperationActivityId $($exportJob.OperationActivityId) -EnvironmentId $SourceEnvironmentId -LcsApiUri $LcsApiUri -WaitForCompletion:$false -SleepInSeconds 60 } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/invoke-d365lcsdatabaserefresh.ps1 ================================================  <# .SYNOPSIS Start a database refresh between 2 environments .DESCRIPTION Start a database refresh between 2 environments from a LCS project .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER SourceEnvironmentId The unique id of the environment that you want to use as the source for the database refresh The Id can be located inside the LCS portal .PARAMETER TargetEnvironmentId The unique id of the environment that you want to use as the target for the database refresh The Id can be located inside the LCS portal .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER SkipInitialStatusFetch Instruct the cmdlet to skip the first fetch of the database refresh status Useful when you have a large script that handles this status validation and you don't want to spend time with this cmdlet 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. Setting this parameter (activate it), will affect the number of output objects. If you skip, only the first response object outputted. .PARAMETER FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE 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" This will start the database refresh between the Source and Target environments. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The target environment is identified by the TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .EXAMPLE PS C:\> Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" This will start the database refresh between the Source and Target environments. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The target environment is identified by the TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> $databaseRefresh = Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -SkipInitialStatusFetch PS C:\> $databaseRefresh | Get-D365LcsDatabaseOperationStatus -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e9" -SleepInSeconds 60 This will start the database refresh between the Source and Target environments. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The target environment is identified by the TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. It will skip the first database refesh status fetch and only output the details from starting the refresh. 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. Will pipe the $databaseRefresh variable to the Get-D365LcsDatabaseOperationStatus cmdlet and get the status from the database refresh job. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -SkipInitialStatusFetch This will start the database refresh between the Source and Target environments. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The target environment is identified by the TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. It will skip the first database refesh status fetch and only output the details from starting the refresh. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -RetryTimeout "00:01:00" 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. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The target environment is identified by the TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .LINK Get-D365LcsApiConfig .LINK Get-D365LcsApiToken .LINK Get-D365LcsAssetValidationStatus .LINK Get-D365LcsDeploymentStatus .LINK Invoke-D365LcsApiRefreshToken .LINK Invoke-D365LcsUpload .LINK Set-D365LcsApiConfig .NOTES 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). 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. 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. Setting the SkipInitialStatusFetch parameter (activate it), will affect the number of output objects. If you skip, only the first response object outputted. 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. Tags: Environment, Config, Configuration, LCS, Database backup, Api, Backup, Restore, Refresh Author: Mötz Jensen (@Splaxi) #> function Invoke-D365LcsDatabaseRefresh { [CmdletBinding()] [OutputType()] param( [int] $ProjectId = $Script:LcsApiProjectId, [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [Parameter(Mandatory = $true)] [string] $SourceEnvironmentId, [Parameter(Mandatory = $true)] [string] $TargetEnvironmentId, [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [switch] $SkipInitialStatusFetch, [switch] $FailOnErrorMessage, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) Invoke-TimeSignal -Start if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } $refreshJob = Start-LcsDatabaseRefreshV2 -ProjectId $ProjectId -BearerToken $BearerToken -SourceEnvironmentId $SourceEnvironmentId -TargetEnvironmentId $TargetEnvironmentId -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout if (Test-PSFFunctionInterrupt) { return } if ($FailOnErrorMessage -and $refreshJob.ErrorMessage) { $messageString = "The request against LCS succeeded, but the response was an error message for the operation: $($refreshJob.ErrorMessage)." $errorMessagePayload = "`r`n$($refreshJob | ConvertTo-Json)" Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $refreshJob Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $refreshJob } $temp = [PSCustomObject]@{ EnvironmentId = "$TargetEnvironmentId"; OperationStatus = "NotStarted"; ProjectId = $ProjectId } #Hack to silence the PSScriptAnalyzer $temp | Out-Null $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" if (-not $SkipInitialStatusFetch) { Get-D365LcsDatabaseOperationStatus -ProjectId $ProjectId -BearerToken $BearerToken -OperationActivityId $($refreshJob.OperationActivityId) -EnvironmentId $TargetEnvironmentId -LcsApiUri $LcsApiUri -WaitForCompletion:$false -SleepInSeconds 60 } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/invoke-d365lcsdeployment.ps1 ================================================  <# .SYNOPSIS Start the deployment of a deployable package .DESCRIPTION Deploy a deployable package from the Asset Library from a LCS project using the API provided by Microsoft .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER AssetId The unique id of the asset / file that you are trying to deploy from LCS .PARAMETER EnvironmentId The unique id of the environment that you want to work against The Id can be located inside the LCS portal Default value can be configured using Set-D365LcsApiConfig .PARAMETER UpdateName Name of the update when you are working against Self-Service environments .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE 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" This will start the deployment of the file located in the Asset Library. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. 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. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "Bearer JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .EXAMPLE PS C:\> Invoke-D365LcsDeployment -AssetId "958ae597-f089-4811-abbd-c1190917eaae" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" This will start the deployment of the file located in the Asset Library. 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. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Invoke-D365LcsDeployment -AssetId "958ae597-f089-4811-abbd-c1190917eaae" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -UpdateName "Release_XYZ" This will start the deployment of the file located in the Asset Library against a Self-Service environment. 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. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The deployment is name "Release_XYZ" by setting the UpdateName parameter, which is mandatory when working against Self-Service environments. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Invoke-D365LcsDeployment -AssetId "958ae597-f089-4811-abbd-c1190917eaae" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -RetryTimeout "00:01:00" 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. 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. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .LINK Get-D365LcsApiConfig .LINK Get-D365LcsApiToken .LINK Get-D365LcsAssetValidationStatus .LINK Get-D365LcsDeploymentStatus .LINK Invoke-D365LcsApiRefreshToken .LINK Invoke-D365LcsUpload .LINK Set-D365LcsApiConfig .NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deploy Author: Mötz Jensen (@Splaxi) #> function Invoke-D365LcsDeployment { [CmdletBinding(DefaultParameterSetName = "VM")] [OutputType()] param( [int] $ProjectId = $Script:LcsApiProjectId, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string] $AssetId, [Parameter(Mandatory = $true)] [string] $EnvironmentId, [Parameter(ParameterSetName = "Self-Service", Mandatory = $true)] [string] $UpdateName, [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [switch] $FailOnErrorMessage, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) process { Invoke-TimeSignal -Start if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } $deploymentStatus = Start-LcsDeploymentV2 -BearerToken $BearerToken -ProjectId $ProjectId -AssetId $AssetId -EnvironmentId $EnvironmentId -UpdateName $UpdateName -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout if (Test-PSFFunctionInterrupt) { return } if ($FailOnErrorMessage -and $deploymentStatus.ErrorMessage) { $messageString = "The request against LCS succeeded, but the response was an error message for the operation: $($deploymentStatus.ErrorMessage)." $errorMessagePayload = "`r`n$($deploymentStatus | ConvertTo-Json)" Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $deploymentStatus } $temp = [PSCustomObject]@{ EnvironmentId = "$TargetEnvironmentId"; OperationStatus = "NotStarted"; ProjectId = $ProjectId } #Hack to silence the PSScriptAnalyzer $temp | Out-Null $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" Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/invoke-d365lcsenvironmentstart.ps1 ================================================  <# .SYNOPSIS Start a specified environment through LCS. .DESCRIPTION Start a specified IAAS environment that is Customer Managed through the LCS API. .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER EnvironmentId The unique id of the environment that you want to take action upon The Id can be located inside the LCS portal .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Invoke-D365LcsEnvironmentStart -ProjectId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will trigger the environment start operation upon the given environment through the LCS API. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" .EXAMPLE PS C:\> Invoke-D365LcsEnvironmentStart -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" This will trigger the environment start operation upon the given environment through the LCS API. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Invoke-D365LcsEnvironmentStart -ProjectId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -RetryTimeout "00:01:00" 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. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .LINK Get-D365LcsApiConfig .LINK Get-D365LcsApiToken .LINK Invoke-D365LcsApiRefreshToken .LINK Set-D365LcsApiConfig .LINK Invoke-D365LcsEnvironmentStop .NOTES Only Customer Managed IAAS environments are supported with this API. Microsoft Managed IAAS environments need to remain online to allow for Microsoft update operations and are not supported with this API. Self-service environments do not have a stop functionality and will not work with this API. Tags: Environment, Start, StartStop, Stop, LCS, Api Author: Mötz Jensen (@Splaxi), Billy Richardson (@richardsondev) #> function Invoke-D365LcsEnvironmentStart { [CmdletBinding()] [OutputType()] param( [int] $ProjectId = $Script:LcsApiProjectId, [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [Parameter(Mandatory = $true)] [string] $EnvironmentId, [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [switch] $FailOnErrorMessage, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) Invoke-TimeSignal -Start if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } $environmentAction = Start-LcsEnvironmentStartStopV2 -ProjectId $ProjectId -BearerToken $BearerToken -EnvironmentId $EnvironmentId -IsStop $False -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout if (Test-PSFFunctionInterrupt) { return } if ($FailOnErrorMessage -and $environmentAction.ErrorMessage) { $messageString = "The request against LCS succeeded, but the response was an error message for the operation: $($environmentAction.ErrorMessage)." $errorMessagePayload = "`r`n$($environmentAction | ConvertTo-Json)" Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $environmentAction Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $environmentAction } $temp = [PSCustomObject]@{ EnvironmentId = "$EnvironmentId"; ProjectId = $ProjectId } #Hack to silence the PSScriptAnalyzer $temp | Out-Null $environmentAction | Select-PSFObject *, "OperationActivityId as ActivityId", "EnvironmentId from temp as EnvironmentId", "ProjectId from temp as ProjectId" -TypeName "D365FO.TOOLS.LCS.Environment.Operation.Status" Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/invoke-d365lcsenvironmentstop.ps1 ================================================  <# .SYNOPSIS Stop a specified environment through LCS. .DESCRIPTION Stop a specified IAAS environment that is Customer Managed through the LCS API. .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER EnvironmentId The unique id of the environment that you want to take action upon The Id can be located inside the LCS portal .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Invoke-D365LcsEnvironmentStop -ProjectId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will trigger the environment stop operation upon the given environment through the LCS API. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" .EXAMPLE PS C:\> Invoke-D365LcsEnvironmentStop -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" This will trigger the environment stop operation upon the given environment through the LCS API. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Invoke-D365LcsEnvironmentStop -ProjectId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -RetryTimeout "00:01:00" 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. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .LINK Get-D365LcsApiConfig .LINK Get-D365LcsApiToken .LINK Invoke-D365LcsApiRefreshToken .LINK Set-D365LcsApiConfig .LINK Invoke-D365LcsEnvironmentStart .NOTES Only Customer Managed IAAS environments are supported with this API. Microsoft Managed IAAS environments need to remain online to allow for Microsoft update operations and are not supported with this API. Self-service environments do not have a stop functionality and will not work with this API. Tags: Environment, Stop, StartStop, Start, LCS, Api Author: Mötz Jensen (@Splaxi), Billy Richardson (@richardsondev) #> function Invoke-D365LcsEnvironmentStop { [CmdletBinding()] [OutputType()] param( [int] $ProjectId = $Script:LcsApiProjectId, [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [Parameter(Mandatory = $true)] [string] $EnvironmentId, [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [switch] $FailOnErrorMessage, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) Invoke-TimeSignal -Start if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } $environmentAction = Start-LcsEnvironmentStartStopV2 -ProjectId $ProjectId -BearerToken $BearerToken -EnvironmentId $EnvironmentId -IsStop $True -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout if (Test-PSFFunctionInterrupt) { return } if ($FailOnErrorMessage -and $environmentAction.ErrorMessage) { $messageString = "The request against LCS succeeded, but the response was an error message for the operation: $($environmentAction.ErrorMessage)." $errorMessagePayload = "`r`n$($environmentAction | ConvertTo-Json)" Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $environmentAction Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $environmentAction } $temp = [PSCustomObject]@{ EnvironmentId = "$EnvironmentId"; ProjectId = $ProjectId } #Hack to silence the PSScriptAnalyzer $temp | Out-Null $environmentAction | Select-PSFObject *, "OperationActivityId as ActivityId", "EnvironmentId from temp as EnvironmentId", "ProjectId from temp as ProjectId" -TypeName "D365FO.TOOLS.LCS.Environment.Operation.Status" Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/invoke-d365lcsupload.ps1 ================================================  <# .SYNOPSIS Upload a file to a LCS project .DESCRIPTION Upload a file to a LCS project using the API provided by Microsoft .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER FilePath Path to the file that you want to upload to the Asset Library on LCS .PARAMETER FileType Type of file you want to upload Valid options: "Model" "Process Data Package" "Software Deployable Package" "GER Configuration" "Data Package" "PowerBI Report Model" "E-Commerce Package" "NuGet Package" "Retail Self-Service Package" "Commerce Cloud Scale Unit Extension" Default value is "Software Deployable Package" .PARAMETER Name Name to be assigned / shown on LCS .PARAMETER Filename Filename to be assigned / shown on LCS Often will it require an extension for it to be accepted .PARAMETER FileDescription Description to be assigned / shown on LCS .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE 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" This will start the upload of a file to the Asset Library. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The file that will be uploaded is based on the FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip". The file type "Software Deployable Package" determines where inside the Asset Library the file will end up. The name inside the Asset Library is based on the Name "Release-2019-05-05". The file name inside the Asset Library is based on the FileName "Release-2019-05-05.zip". The description inside the Asset Library is based on the FileDescription "Build based on sprint: SuperSprint-1". The request will authenticate with the BearerToken "Bearer JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .EXAMPLE PS C:\> Invoke-D365LcsUpload -FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip" -FileType "SoftwareDeployablePackage" -FileName "Release-2019-05-05.zip" This will start the upload of a file to the Asset Library. The file that will be uploaded is based on the FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip". The file type "Software Deployable Package" determines where inside the Asset Library the file will end up. The file name inside the Asset Library is based on the FileName "Release-2019-05-05.zip". All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Invoke-D365LcsUpload -FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip" This will start the upload of a file to the Asset Library. The file that will be uploaded is based on the FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip". All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .EXAMPLE PS C:\> Invoke-D365LcsUpload -FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip" -RetryTimeout "00:01:00" 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. The file that will be uploaded is based on the FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip". All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. .LINK Get-D365LcsApiConfig .LINK Get-D365LcsApiToken .LINK Get-D365LcsAssetValidationStatus .LINK Get-D365LcsDeploymentStatus .LINK Invoke-D365LcsApiRefreshToken .LINK Invoke-D365LcsDeployment .LINK Set-D365LcsApiConfig .NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token Author: Mötz Jensen (@Splaxi) #> function Invoke-D365LcsUpload { [CmdletBinding()] [OutputType()] param( [int]$ProjectId = $Script:LcsApiProjectId, [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [Parameter(Mandatory = $true)] [string] $FilePath, [LcsAssetFileType] $FileType = [LcsAssetFileType]::SoftwareDeployablePackage, [string] $Name, [string] $Filename, [string] $FileDescription, [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [switch] $FailOnErrorMessage, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) Invoke-TimeSignal -Start $fileNameExtracted = Split-Path $FilePath -Leaf if ($Filename -eq "") { $Filename = $fileNameExtracted } if ($Name -eq "") { $Name = [System.IO.Path]::GetFileNameWithoutExtension($FilePath) } if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } $blobDetails = Start-LcsUploadV2 -Token $BearerToken -ProjectId $ProjectId -FileType $FileType -LcsApiUri $LcsApiUri -Name $Name -FileName $Filename -Description $FileDescription -RetryTimeout $RetryTimeout if (Test-PSFFunctionInterrupt) { return } if ($FailOnErrorMessage -and $blobDetails.ErrorMessage) { $messageString = "The request against LCS succeeded, but the response was an error message for the operation: $($blobDetails.ErrorMessage)." $errorMessagePayload = "`r`n$($blobDetails | ConvertTo-Json)" Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $blobDetails Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $blobDetails } Write-PSFMessage -Level Verbose -Message "Start response" -Target $blobDetails $uploadResponse = Copy-FileToLcsBlob -FilePath $FilePath -FullUri $blobDetails.FileLocation if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Upload response" -Target $uploadResponse $ackResponse = Complete-LcsUploadV2 -Token $BearerToken -ProjectId $ProjectId -AssetId $blobDetails.Id -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout if (Test-PSFFunctionInterrupt) { return } if ($FailOnErrorMessage -and $ackResponse.ErrorMessage) { $messageString = "The request against LCS succeeded, but the response was an error message for the operation: $($ackResponse.ErrorMessage)." $errorMessagePayload = "`r`n$($ackResponse | ConvertTo-Json)" Write-PSFMessage -Level Host -Message $messageString -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $ackResponse Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($errorMessagePayload))) -Target $ackResponse } Write-PSFMessage -Level Verbose -Message "Commit response" -Target $ackResponse Invoke-TimeSignal -End [PSCustomObject]@{ AssetId = $blobDetails.Id Name = $Name Filename = $Filename } } ================================================ FILE: d365fo.tools/functions/invoke-d365modulecompile.ps1 ================================================  <# .SYNOPSIS Compile a package / module / model .DESCRIPTION Compile a package / module / model using the builtin "xppc.exe" executable to compile source code .PARAMETER Module The package to compile .PARAMETER OutputDir The path to the folder to save generated artifacts .PARAMETER LogPath Path where you want to store the log outputs generated from the compiler Also used as the path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory .PARAMETER ReferenceDir The full path of a folder containing all assemblies referenced from X++ code Default path is the same as the aos service PackagesLocalDirectory .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER XRefSqlServer The name of the SQL server where the cross references database is located; the default is "$env:COMPUTERNAME" This parameter is only used for XRefGenerationOnly .PARAMETER XRefDbName The name of the cross references database; the default is "DYNAMICSXREFDB" This parameter is only used for XRefGenerationOnly .PARAMETER XRefGeneration Instruct the cmdlet to enable the generation of XRef metadata while running the compile .PARAMETER XRefGenerationOnly Instruct the cmdlet to only generate XRef metadata while running the compile and not update the assemblies and PDB files .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .EXAMPLE PS C:\> Invoke-D365ModuleCompile -Module MyModel This will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package. The default output from the compile will be silenced. If an error should occur, both the standard output and error output will be written to the console / host. .EXAMPLE PS C:\> Invoke-D365ModuleCompile -Module MyModel -ShowOriginalProgress This will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package. The output from the compile will be written to the console / host. .EXAMPLE PS C:\> Invoke-D365ModuleCompile -Module MyModel -XRefGeneration This will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package. The default output from the compile will be silenced. The compiler will generate XRef metadata while compiling. If an error should occur, both the standard output and error output will be written to the console / host. .EXAMPLE PS C:\> Invoke-D365ModuleCompile -Module MyModel -XRefGenerationOnly This will use the default paths and start the xppc.exe with the needed parameters to only generate cross references for the MyModel package. .EXAMPLE PS C:\> Get-D365Module -ExcludeBinaryModules -InDependencyOrder | Invoke-D365ModuleCompile -XRefGenerationOnly -ShowOriginalProgress This will update all cross references, keeping the assemblies and PDB files unmodified. The output from the compile will be written to the console / host. .NOTES Tags: Compile, Model, Servicing, X++ Author: Ievgen Miroshnikov (@IevgenMir) Author: Mötz Jensen (@Splaxi) Author: Frank Hüther (@FrankHuether) #> function Invoke-D365ModuleCompile { [CmdletBinding()] [OutputType('[PsCustomObject]')] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias("ModuleName")] [string] $Module, [Alias('Output')] [string] $OutputDir = $Script:MetaDataDir, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ModuleCompile"), [string] $MetaDataDir = $Script:MetaDataDir, [string] $ReferenceDir = $Script:MetaDataDir, [string] $BinDir = $Script:BinDirTools, [string] $XRefSqlServer = $env:COMPUTERNAME, [string] $XRefDbName = "DYNAMICSXREFDB", [switch] $XRefGeneration, [switch] $XRefGenerationOnly, [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) begin { Invoke-TimeSignal -Start $tool = "xppc.exe" $executable = Join-Path -Path $BinDir -ChildPath $tool if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return } if (-not (Test-PathExists -Path $executable -Type Leaf)) { return } if (-not (Test-PathExists -Path $LogPath -Type Container -Create)) { return } } process { $logDirModule = Join-Path -Path $LogPath -ChildPath $Module $outputDirModule = Join-Path -Path $OutputDir -ChildPath $Module if (-not (Test-PathExists -Path $logDirModule -Type Container -Create)) { return } if (Test-PSFFunctionInterrupt) { return } $logFile = Join-Path -Path $logDirModule -ChildPath "Dynamics.AX.$Module.xppc.log" $logXmlFile = Join-Path -Path $logDirModule -ChildPath "Dynamics.AX.$Module.xppc.xml" $params = @("-metadata=`"$MetaDataDir`"", "-modelmodule=`"$Module`"", "-output=`"$outputDirModule\bin`"", "-referencefolder=`"$ReferenceDir`"", "-log=`"$logFile`"", "-xmlLog=`"$logXmlFile`"", "-verbose" ) if ($XRefGenerationOnly) { $params += @("-xrefonly", "-xrefSqlServer=`"$XRefSqlServer`"", "-xrefDbName=`"$XRefDbName`"" ) } elseif ($XRefGeneration) { $params += "-xref" } Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $logDirModule if ($OutputCommandOnly) { return } [PSCustomObject]@{ LogFile = $logFile XmlLogFile = $logXmlFile PSTypeName = 'D365FO.TOOLS.ModuleCompileOutput' } } end { Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/invoke-d365modulefullcompile.ps1 ================================================  <# .SYNOPSIS Compile a package .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 .PARAMETER Module The package to compile .PARAMETER OutputDir The path to the folder to save assemblies .PARAMETER LogPath Path where you want to store the log outputs generated from the compiler Also used as the path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER MetaDataDir The path to the meta data directory for the environment .PARAMETER ReferenceDir The full path of a folder containing all assemblies referenced from X++ code .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .EXAMPLE PS C:\> Invoke-D365ModuleFullCompile -Module MyModel This will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package. The default output from all the different steps will be silenced. .EXAMPLE PS C:\> Invoke-D365ModuleFullCompile -Module MyModel -ShowOriginalProgress This will use the default paths and start the xppc.exe with the needed parameters to copmile MyModel package. The default output from the different steps will be written to the console / host. .NOTES Tags: Compile, Model, Servicing Author: Ievgen Miroshnikov (@IevgenMir) Author: Mötz Jensen (@Splaxi) #> function Invoke-D365ModuleFullCompile { [CmdletBinding()] [OutputType('[PsCustomObject]')] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias("ModuleName")] [string] $Module, [Alias('Output')] [string] $OutputDir = $Script:MetaDataDir, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ModuleCompile"), [string] $MetaDataDir = $Script:MetaDataDir, [string] $ReferenceDir = $Script:MetaDataDir, [string] $BinDir = $Script:BinDirTools, [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) begin { Invoke-TimeSignal -Start if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return } if (-not (Test-PathExists -Path $LogPath -Type Container -Create)) { return } } process { $resModuleCompile = Invoke-D365ModuleCompile @PSBoundParameters $resLabelGeneration = Invoke-D365ModuleLabelGeneration @PSBoundParameters $resReportsCompile = Invoke-D365ModuleReportsCompile @PSBoundParameters $resModuleCompile $resLabelGeneration $resReportsCompile } end { Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/invoke-d365modulelabelgeneration.ps1 ================================================  <# .SYNOPSIS Generate labels for a package / module / model .DESCRIPTION Generate labels for a package / module / model using the builtin "labelc.exe" .PARAMETER Module Name of the package that you want to work against .PARAMETER OutputDir The path to the folder to save generated artifacts .PARAMETER LogPath Path where you want to store the log outputs generated from the compiler Also used as the path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory .PARAMETER ReferenceDir The full path of a folder containing all assemblies referenced from X++ code Default path is the same as the aos service PackagesLocalDirectory .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .EXAMPLE PS C:\> Invoke-D365ModuleLabelGeneration -Module MyModel This will use the default paths and start the labelc.exe with the needed parameters to labels from the MyModel package. The default output from the generation process will be silenced. If an error should occur, both the standard output and error output will be written to the console / host. .EXAMPLE PS C:\> Invoke-D365ModuleLabelGeneration -Module MyModel -ShowOriginalProgress This will use the default paths and start the labelc.exe with the needed parameters to labels from the MyModel package. The output from the compile will be written to the console / host. .NOTES Tags: Compile, Model, Servicing, Label, Labels Author: Ievgen Miroshnikov (@IevgenMir) Author: Mötz Jensen (@Splaxi) #> function Invoke-D365ModuleLabelGeneration { [CmdletBinding()] [OutputType('[PsCustomObject]')] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias("ModuleName")] [string] $Module, [Alias('Output')] [string] $OutputDir = $Script:MetaDataDir, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ModuleCompile"), [string] $MetaDataDir = $Script:MetaDataDir, [string] $ReferenceDir = $Script:MetaDataDir, [string] $BinDir = $Script:BinDirTools, [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) begin { Invoke-TimeSignal -Start $tool = "labelc.exe" $executable = Join-Path -Path $BinDir -ChildPath $tool if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return } if (-not (Test-PathExists -Path $executable -Type Leaf)) { return } if (-not (Test-PathExists -Path $LogPath -Type Container -Create)) { return } } process { $logDirModule = Join-Path -Path $LogPath -ChildPath $Module $outputDirModule = Join-Path -Path $OutputDir -ChildPath $Module if (-not (Test-PathExists -Path $logDirModule -Type Container -Create)) { return } if (Test-PSFFunctionInterrupt) { return } $logFile = Join-Path -Path $logDirModule -ChildPath "Dynamics.AX.$Module.labelc.log" $logErrorFile = Join-Path -Path $logDirModule -ChildPath "Dynamics.AX.$Module.labelc.err" $params = @("-metadata=`"$MetaDataDir`"", "-modelmodule=`"$Module`"", "-output=`"$outputDirModule\Resources`"", "-outlog=`"$logFile`"", "-errlog=`"$logErrorFile`"" ) Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $logDirModule if ($OutputCommandOnly) { return } [PSCustomObject]@{ OutLogFile = $logFile ErrorLogFile = $logErrorFile PSTypeName = 'D365FO.TOOLS.ModuleLabelGenerationOutput' } } end { Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/invoke-d365modulereportscompile.ps1 ================================================  <# .SYNOPSIS Generate reports for a package / module / model .DESCRIPTION Generate reports for a package / module / model using the builtin "ReportsC.exe" .PARAMETER Module Name of the package that you want to work against .PARAMETER OutputDir The path to the folder to save generated artifacts .PARAMETER LogPath Path where you want to store the log outputs generated from the compiler Also used as the path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory .PARAMETER ReferenceDir The full path of a folder containing all assemblies referenced from X++ code Default path is the same as the aos service PackagesLocalDirectory .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .EXAMPLE PS C:\> Invoke-D365ModuleReportsCompile -Module MyModel This will use the default paths and start the ReportsC.exe with the needed parameters to compile the reports from the MyModel package. The default output from the reports compile will be silenced. If an error should occur, both the standard output and error output will be written to the console / host. .EXAMPLE PS C:\> Invoke-D365ModuleReportsCompile -Module MyModel -ShowOriginalProgress This will use the default paths and start the ReportsC.exe with the needed parameters to compile the reports from the MyModel package. The output from the compile will be written to the console / host. .NOTES Tags: Compile, Model, Servicing, Report, Reports Author: Ievgen Miroshnikov (@IevgenMir) Author: Mötz Jensen (@Splaxi) #> function Invoke-D365ModuleReportsCompile { [CmdletBinding()] [OutputType('[PsCustomObject]')] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias("ModuleName")] [string] $Module, [Alias('Output')] [string] $OutputDir = $Script:MetaDataDir, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ModuleCompile"), [string] $MetaDataDir = $Script:MetaDataDir, [string] $ReferenceDir = $Script:MetaDataDir, [string] $BinDir = $Script:BinDirTools, [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) begin { Invoke-TimeSignal -Start $tool = "ReportsC.exe" $executable = Join-Path -Path $BinDir -ChildPath $tool if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return } if (-not (Test-PathExists -Path $executable -Type Leaf)) { return } if (-not (Test-PathExists -Path $LogPath -Type Container -Create)) { return } } process { $logDirModule = Join-Path -Path $LogPath -ChildPath $Module $outputDirModule = Join-Path -Path $OutputDir -ChildPath $Module if (-not (Test-PathExists -Path $logDirModule -Type Container -Create)) { return } if (Test-PSFFunctionInterrupt) { return } $logFile = Join-Path -Path $logDirModule -ChildPath "Dynamics.AX.$Module.ReportsC.log" $logXmlFile = Join-Path -Path $logDirModule -ChildPath "Dynamics.AX.$Module.ReportsC.xml" $params = @("-metadata=`"$MetaDataDir`"", "-modelmodule=`"$Module`"", "-LabelsPath=`"$MetaDataDir`"", "-output=`"$outputDirModule\Reports`"", "-log=`"$logFile`"", "-xmlLog=`"$logXmlFile`"" ) Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $logDirModule if ($OutputCommandOnly) { return } [PSCustomObject]@{ LogFile = $logFile XmlLogFile = $logXmlFile PSTypeName = 'D365FO.TOOLS.ModuleReportsCompileOutput' } } end { Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/invoke-d365processmodule.ps1 ================================================  <# .SYNOPSIS Process a specific or multiple modules (compile, deploy reports and sync) .DESCRIPTION Process a specific or multiple modules by invoking the following functions (based on flags) - Invoke-D365ModuleFullCompile function - Publish-D365SsrsReport to deploy the reports of a module - Invoke-D365DBSyncPartial to sync the table and extension elements for module .PARAMETER Module Name of the module that you want to process Accepts wildcards for searching. E.g. -Module "Application*Adaptor" Default value is "*" which will search for all modules .PARAMETER ExecuteCompile Switch/flag to determine if the compile function should be executed for requested modules .PARAMETER ExecuteSync Switch/flag to determine if the databasesync function should be executed for requested modules .PARAMETER ExecuteDeployReports Switch/flag to determine if the deploy reports function should be executed for requested modules .PARAMETER OutputDir The path to the folder to save assemblies .PARAMETER LogPath Path where you want to store the log outputs generated from the compiler Also used as the path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER MetaDataDir The path to the meta data directory for the environment .PARAMETER ReferenceDir The full path of a folder containing all assemblies referenced from X++ code .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .EXAMPLE PS C:\> Invoke-D365ProcessModule -Module "Application*Adaptor" -ExecuteCompile Retrieve the list of installed packages / modules where the name fits the search "Application*Adaptor". For every value of the list perform the following: * Invoke-D365ModuleFullCompile with the needed parameters to compile current module value package. The default output from all the different steps will be silenced. .EXAMPLE PS C:\> Invoke-D365ProcessModule -Module "Application*Adaptor" -ExecuteSync Retrieve the list of installed packages / modules where the name fits the search "Application*Adaptor". For every value of the list perform the following: * Invoke-D365DBSyncPartial with the needed parameters to sync current module value table and extension elements. The default output from all the different steps will be silenced. .EXAMPLE PS C:\> Invoke-D365ProcessModule -Module "Application*Adaptor" -ExecuteDeployReports Retrieve the list of installed packages / modules where the name fits the search "Application*Adaptor". For every value of the list perform the following: * Publish-D365SsrsReport with the required parameters to deploy all reports of current module The default output from all the different steps will be silenced. .EXAMPLE PS C:\> Invoke-D365ProcessModule -Module "Application*Adaptor" -ExecuteCompile -ExecuteSync -ExecuteDeployReports Retrieve the list of installed packages / modules where the name fits the search "Application*Adaptor". For every value of the list perform the following: * Invoke-D365ModuleFullCompile with the needed parameters to compile current module package. * Invoke-D365DBSyncPartial with the needed parameters to sync current module table and extension elements. * Publish-D365SsrsReport with the required parameters to deploy all reports of current module The default output from all the different steps will be silenced. .NOTES Tags: Compile, Model, Servicing, Database, Synchronization Author: Jasper Callens - Cegeka #> function Invoke-D365ProcessModule { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [Alias("ModuleName")] [string] $Module, [switch] $ExecuteCompile = $false, [switch] $ExecuteSync = $false, [switch] $ExecuteDeployReports = $false, [Alias('Output')] [string] $OutputDir = $Script:MetaDataDir, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ModuleCompile"), [string] $MetaDataDir = $Script:MetaDataDir, [string] $ReferenceDir = $Script:MetaDataDir, [string] $BinDir = $Script:BinDirTools, [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) begin { Invoke-TimeSignal -Start } process { # Only execute the code if any of the flags are set if ($ExecuteCompile -or $ExecuteSync -or $ExecuteDeployReports) { # Retrieve all modules that match provided $Module $moduleResults = Get-D365Module -Name $Module # Output information on which modules that will be compiled and synced Write-PSFMessage -Level Host -Message "Modules to process: " $moduleResults | ForEach-Object { Write-PSFMessage -Level Host -Message " - $($_.Module) " } # Empty list for all modules that have to be compiled $modulesToCompile = @() # Empty list for all modules of which the reports have to be deployed $modulesToDeployReports = @() # Create empty lists for all sync-base and sync-extension elements $syncList = @() $syncExtensionsList = @() # Loop every resulting module result and fill the required 'processing' lists based on the flags foreach ($moduleElement in $moduleResults) { if ($ExecuteCompile) { $modulesToCompile += $moduleElement } if ($ExecuteDeployReports) { $modulesToDeployReports += $moduleElement } if ($ExecuteSync) { # Retrieve the sync element of current module $moduleSyncElements = Get-SyncElements -ModuleName $moduleElement.Module # Add base and extensions elements to the sync lists $syncList += $moduleSyncElements.BaseSyncElements $syncExtensionsList += $moduleSyncElements.ExtensionSyncElements } } if ($ExecuteCompile) { # Loop over every module to compile and execute compile function foreach ($moduleToCompile in $modulesToCompile) { # Build parameters for the full compile function $fullCompileParams = @{ Module = $moduleToCompile.Module; OutputDir = $OutputDir; LogPath = $LogPath; MetaDataDir = $MetaDataDir; ReferenceDir = $ReferenceDir; BinDir = $BinDir; ShowOriginalProgress = $ShowOriginalProgress; OutputCommandOnly = $OutputCommandOnly } # Call the full compile using required parameters $resModuleCompileFull = Invoke-D365ModuleFullCompile @fullCompileParams # Output results of full compile $resModuleCompileFull } } if ($ExecuteDeployReports) { # Loop over every module to deploy reports and execute deploy report function foreach ($moduleToDeployReports in $modulesToDeployReports) { # Build parameters for the model report deployment $fullDeployParams = @{ Module = $moduleToDeployReports.Module; LogFile = "$LogPath\$($moduleToDeployReports.Module).log"; } if ($OutputCommandOnly) { Write-PSFMessage -Level Host -Message "Publish-D365SsrsReport $($fullDeployParams -join ' ')" } else { $resModuleDeployReports = Publish-D365SsrsReport @fullDeployParams $resModuleDeployReports } } } if ($ExecuteSync) { # Build parameters for the partial sync function $syncParams = @{ SyncList = $syncList; SyncExtensionsList = $syncExtensionsList; BinDirTools = $BinDir; MetadataDir = $MetaDataDir; ShowOriginalProgress = $ShowOriginalProgress; OutputCommandOnly = $OutputCommandOnly } # Call the partial sync using required parameters $resSyncModule = Invoke-D365DBSyncPartial @syncParams $resSyncModule } } else { Write-PSFMessage -Level Output -Message "No process flags were set. Nothing will be processed" } } end { Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/invoke-d365rearmwindows.ps1 ================================================  <# .SYNOPSIS Invokes the Rearm of Windows license .DESCRIPTION Function used for invoking the rearm functionality inside Windows .PARAMETER Restart Instruct the cmdlet to restart the machine .EXAMPLE PS C:\> Invoke-D365ReArmWindows This will re arm the Windows installation if there is any activation retries left .EXAMPLE PS C:\> Invoke-D365ReArmWindows -Restart This will re arm the Windows installation if there is any activation retries left and restart the computer. .NOTES Author: Mötz Jensen (@Splaxi) #> function Invoke-D365ReArmWindows { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 1)] [switch]$Restart ) Write-PSFMessage -Level Verbose -Message "Invoking the rearm process." $instance = Get-CimInstance -Class SoftwareLicensingService -Namespace root/cimv2 -ComputerName . Invoke-CimMethod -InputObject $instance -MethodName ReArmWindows if ($Restart) { Restart-Computer -Force } } ================================================ FILE: d365fo.tools/functions/invoke-d365runbookanalyzer.ps1 ================================================  <# .SYNOPSIS Analyze the runbook .DESCRIPTION Get all the important details from a failed runbook .PARAMETER Path Path to the runbook file that you work against .PARAMETER FailedOnly Instruct the cmdlet to only output failed steps .PARAMETER FailedOnlyAsObjects Instruct the cmdlet to only output failed steps as objects .EXAMPLE PS C:\> Invoke-D365RunbookAnalyzer -Path "C:\DynamicsAX\InstallationRecords\Runbooks\Runbook.xml" This will analyze the Runbook.xml and output all the details about failed steps, the connected error logs and all the unprocessed steps. .EXAMPLE PS C:\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. .EXAMPLE PS C:\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnly This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. The output from Invoke-D365RunbookAnalyzer will only contain failed steps. .EXAMPLE PS C:\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnlyAsObjects This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. The output from Invoke-D365RunbookAnalyzer will only contain failed steps. The output will be formatted as PSCustomObjects, to be used as variables or piping. .EXAMPLE PS C:\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnlyAsObjects | Get-D365RunbookLogFile -Path "C:\Temp\PU35" -OpenInEditor This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. The output from Invoke-D365RunbookAnalyzer will only contain failed steps. The Get-D365RunbookLogFile will open all log files for the failed step. .EXAMPLE PS C:\> Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer | Out-File "C:\Temp\d365fo.tools\runbook-analyze-results.xml" This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. The output will be saved into the "C:\Temp\d365fo.tools\runbook-analyze-results.xml" file. .EXAMPLE PS C:\> Get-D365Runbook -Latest | Backup-D365Runbook -Force | Invoke-D365RunbookAnalyzer This will get the latest runbook from the default location. This will backup the file onto the default "c:\temp\d365fo.tools\runbookbackups\". This will start the Runbook Analyzer on the backup file. .NOTES Tags: Runbook, Servicing, Hotfix, DeployablePackage, Deployable Package, InstallationRecordsDirectory, Installation Records Directory Author: Mötz Jensen (@Splaxi) #> function Invoke-D365RunbookAnalyzer { [CmdletBinding(DefaultParameterSetName="Default")] [OutputType('System.String')] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true, ParameterSetName = "Default")] [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true, ParameterSetName = "FailedOnly")] [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true, ParameterSetName = "FailedOnlyAsObjects")] [Alias('File')] [string] $Path, [Parameter(ParameterSetName = "FailedOnly")] [switch] $FailedOnly, [Parameter(ParameterSetName = "FailedOnlyAsObjects")] [switch] $FailedOnlyAsObjects ) process { if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } $null = $sb = New-Object System.Text.StringBuilder $null = $sb.AppendLine("") [xml]$xmlRunbook = Get-Content $Path $failedObjs = New-Object System.Collections.Generic.List[System.Object] $failedSteps = $xmlRunbook.SelectNodes("//RunbookStepList/Step/StepState[text()='Failed']") $failedSteps | ForEach-Object { $null = $sb.AppendLine("") $stepId = $_.ParentNode | Select-Object -ExpandProperty childnodes | Where-Object { $_.name -like 'ID' } | Select-Object -ExpandProperty InnerText $failedLogs = $xmlRunbook.SelectNodes("//RunbookLogs/Log/StepID[text()='$stepId']") $failedObjs.Add([PsCustomObject]@{Step = "$stepId" }) $null = $sb.AppendLine($_.ParentNode.OuterXml) $failedLogs | ForEach-Object { $null = $sb.AppendLine( $_.ParentNode.OuterXml) } $null = $sb.AppendLine("") } if ((-not $FailedOnly) -and (-not $FailedOnlyAsObjects)) { $inProgressSteps = $xmlRunbook.SelectNodes("//RunbookStepList/Step/StepState[text()='InProgress']") $null = $sb.AppendLine("") $inProgressSteps | ForEach-Object { $null = $sb.AppendLine( $_.ParentNode.OuterXml) } $null = $sb.AppendLine("") $unprocessedSteps = $xmlRunbook.SelectNodes("//RunbookStepList/Step/StepState[text()='NotStarted']") $null = $sb.AppendLine("") $unprocessedSteps | ForEach-Object { $null = $sb.AppendLine( $_.ParentNode.OuterXml) } $null = $sb.AppendLine("") } $null = $sb.AppendLine("") if ($FailedOnlyAsObjects) { $failedObjs.ToArray() } else { [xml]$xmlRaw = $sb.ToString() $stringWriter = New-Object System.IO.StringWriter; $xmlWriter = New-Object System.Xml.XmlTextWriter $stringWriter; $xmlWriter.Formatting = "indented"; $xmlRaw.WriteTo($xmlWriter); $xmlWriter.Flush(); $stringWriter.Flush(); $stringWriter.ToString(); } } } ================================================ FILE: d365fo.tools/functions/invoke-d365scdpbundleinstall.ps1 ================================================  <# .SYNOPSIS Invoke the SCDPBundleInstall.exe file .DESCRIPTION A cmdlet that wraps some of the cumbersome work of installing updates / hotfixes into a streamlined process .PARAMETER InstallOnly Instructs the cmdlet to only run the Install option and ignore any TFS / VSTS folders and source control in general Use it when testing an update on a local development machine (VM) / onebox .PARAMETER Command The command / job you want the cmdlet to execute Valid options are: Prepare Install Default value is "Prepare" .PARAMETER Path Path to the update package that you want to install into the environment The cmdlet only supports an already extracted ".axscdppkg" file .PARAMETER MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory .PARAMETER TfsWorkspaceDir The path to the TFS Workspace directory that you want to work against Default path is the same as the aos service PackagesLocalDirectory .PARAMETER TfsUri The URI for the TFS Team Site / VSTS Portal that you want to work against Default URI is the one that is configured from inside Visual Studio .PARAMETER ShowModifiedFiles Switch to instruct the cmdlet to show all the modified files afterwards .PARAMETER ShowProgress Switch to instruct the cmdlet to output progress details while servicing the installation .EXAMPLE PS C:\> Invoke-D365SCDPBundleInstall -Path "c:\temp\HotfixPackageBundle.axscdppkg" -InstallOnly This will install the "HotfixPackageBundle.axscdppkg" into the default PackagesLocalDirectory location on the machine. .NOTES Tags: Hotfix, Hotfixes, Updates, Prepare, VSTS, axscdppkg Author: Mötz Jensen (@splaxi) Author: Tommy Skaue (@skaue) #> function Invoke-D365SCDPBundleInstall { [CmdletBinding(DefaultParameterSetName = 'InstallOnly')] param ( [Parameter(Mandatory = $True, ParameterSetName = 'InstallOnly', Position = 0 )] [switch] $InstallOnly, [Parameter(Mandatory = $false, ParameterSetName = 'Tfs', Position = 0 )] [ValidateSet('Prepare', 'Install')] [string] $Command = 'Prepare', [Parameter(Mandatory = $True, Position = 1 )] [Alias('Hotfix')] [Alias('File')] [string] $Path, [Parameter(Mandatory = $False, Position = 2 )] [string] $MetaDataDir = "$Script:MetaDataDir", [Parameter(Mandatory = $False, ParameterSetName = 'Tfs', Position = 3 )] [string] $TfsWorkspaceDir = "$Script:MetaDataDir", [Parameter(Mandatory = $False, ParameterSetName = 'Tfs', Position = 4 )] [string] $TfsUri = "$Script:TfsUri", [Parameter(Mandatory = $False, Position = 4 )] [switch] $ShowModifiedFiles, [Parameter(Mandatory = $False, Position = 5 )] [switch] $ShowProgress ) if (!$script:IsAdminRuntime) { Write-PSFMessage -Level Host -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." Stop-PSFFunction -Message "Stopping because the function is not run elevated" return } Invoke-TimeSignal -Start $StartTime = Get-Date $executable = Join-Path $Script:BinDir "\bin\SCDPBundleInstall.exe" if (!(Test-PathExists -Path $Path, $executable -Type Leaf)) { return } if (!(Test-PathExists -Path $MetaDataDir -Type Container)) { return } Unblock-File -Path $Path #File is typically downloaded and extracted if ($InstallOnly) { $param = @("-install", "-packagepath=$Path", "-metadatastorepath=$MetaDataDir") } else { if ($TfsUri -eq "") { Write-PSFMessage -Level Host -Message "No TFS URI provided. Unable to complete the command." Stop-PSFFunction -Message "Stopping because missing TFS URI parameter." return } switch ($Command) { "Prepare" { $param = @("-prepare") } "Install" { $param = @("-install") } } $param = $param + @("-packagepath=`"$Path`"", "-metadatastorepath=`"$MetaDataDir`"", "-tfsworkspacepath=`"$TfsWorkspaceDir`"", "-tfsprojecturi=`"$TfsUri`"") } Write-PSFMessage -Level Verbose -Message "Invoking SCDPBundleInstall.exe with $Command" -Target $param if ($ShowProgress) { #! We should consider to redirect the standard output & error like this: https://stackoverflow.com/questions/8761888/capturing-standard-out-and-error-with-start-process #Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly $process = Start-Process -FilePath $executable -ArgumentList $param -PassThru while (-not ($process.HasExited)) { $timeout = New-TimeSpan -Days 1 $stopwatch = [Diagnostics.StopWatch]::StartNew(); $bundleRoot = "$env:localappdata\temp\SCDPBundleInstall" [xml]$manifest = Get-Content $(join-path $bundleRoot "PackageDependencies.dgml") -ErrorAction SilentlyContinue $bundleCounter = 0 if ($manifest) { $bundleTotalCount = $manifest.DirectedGraph.Nodes.ChildNodes.Count } while ($manifest -and (-not ($process.HasExited)) -and $stopwatch.elapsed -lt $timeout) { $currentBundleFolder = Get-ChildItem $bundleRoot -Directory -ErrorAction SilentlyContinue if ($currentBundleFolder) { $currentBundle = $currentBundleFolder.Name if ($announcedBundle -ne $currentBundle) { $announcedBundle = $currentBundle $bundleCounter = $bundleCounter + 1 Write-PSFMessage -Level Verbose -Message "$bundleCounter/$bundleTotalCount : Processing hotfix package $announcedBundle" } } } Start-Sleep -Milliseconds 100 } } else { #! We should consider to redirect the standard output & error like this: https://stackoverflow.com/questions/8761888/capturing-standard-out-and-error-with-start-process #Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly Start-Process -FilePath $executable -ArgumentList $param -NoNewWindow -Wait } if ($ShowModifiedFiles) { $res = Get-ChildItem -Path $MetaDataDir -Recurse | Where-Object { $_.LastWriteTime -gt $StartTime } $res | ForEach-Object { Write-PSFMessage -Level Verbose -Message "Object modified by the install: $($_.FullName)" } $res } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/invoke-d365sdpinstall.ps1 ================================================  <# .SYNOPSIS Install a Software Deployable Package (SDP) .DESCRIPTION A cmdlet that wraps some of the cumbersome work into a streamlined process. The process for a legacy (i.e. non unified) environment are detailed in the Microsoft documentation here: https://docs.microsoft.com/en-us/dynamics365/unified-operations/dev-itpro/deployment/install-deployable-package .PARAMETER Path Path to the update package that you want to install into the environment The cmdlet supports a path to a zip-file or directory with the unpacked contents. .PARAMETER MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory .PARAMETER QuickInstallAll Use this switch to let the runbook reside in memory. You will not get a runbook on disc which you can examine for steps .PARAMETER DevInstall Use this when running on developer box without administrator privileges (Run As Administrator) .PARAMETER Command The command you want the cmdlet to execute when it runs the AXUpdateInstaller.exe Valid options are: SetTopology Generate Import Execute RunAll ReRunStep SetStepComplete Export VersionCheck The default value is "SetTopology" .PARAMETER Step The step number that you want to work against .PARAMETER RunbookId The runbook id of the runbook that you want to work against Default value is "Runbook" .PARAMETER LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .PARAMETER TopologyFile Provide a custom topology file to use. By default, the cmdlet will use the DefaultTopologyData.xml file in the package directory. .PARAMETER UseExistingTopologyFile Use this switch to indicate that the topology file is already updated and should not be updated again. .PARAMETER UnifiedDevelopmentEnvironment Use this switch to install the package in a Unified Development Environment (UDE). .PARAMETER IncludeFallbackRetailServiceModels Include fallback retail service models in the topology file This parameter is to support backward compatibility in this scenario: Installing the first update on a local VHD where the information about the installed service models may not be available and where the retail components are installed. More information about this can be found at https://github.com/d365collaborative/d365fo.tools/issues/878 .PARAMETER Force Instruct the cmdlet to overwrite the "extracted" folder if it exists Used when the input is a zip file, that will auto extract to a folder named like the zip file. .PARAMETER ForceFallbackServiceModels Force the use of the fallback list of known service model names This parameter supports update scenarios primarily on local VHDs where the information about the installed service models may be incomplete. In such a case, the user receives a warning and a suggestion to use this parameter. .EXAMPLE PS C:\> Invoke-D365SDPInstall -Path "c:\temp\package.zip" -QuickInstallAll This will install the package contained in the c:\temp\package.zip file using a runbook in memory while executing. .EXAMPLE PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -DevInstall This will install the extracted package in c:\temp\ using a runbook in memory while executing. 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. .EXAMPLE PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -Command SetTopology PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -Command Generate -RunbookId 'MyRunbook' PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -Command Import -RunbookId 'MyRunbook' PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -Command Execute -RunbookId 'MyRunbook' Manual operations that first create Topology XML from current environment, then generate runbook with id 'MyRunbook', then import it and finally execute it. .EXAMPLE PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -Command RunAll Create Topology XML from current environment. Using default runbook id 'Runbook' and run all the operations from generate, to import to execute. .EXAMPLE PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -Command RerunStep -Step 18 -RunbookId 'MyRunbook' Rerun runbook with id 'MyRunbook' from step 18. .EXAMPLE PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -Command SetStepComplete -Step 24 -RunbookId 'MyRunbook' Mark step 24 complete in runbook with id 'MyRunbook' and continue the runbook from the next step. .EXAMPLE PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -Command SetTopology -TopologyFile "c:\temp\MyTopology.xml" Update the MyTopology.xml file with all the installed services on the machine. .EXAMPLE PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -Command RunAll -TopologyFile "c:\temp\MyTopology.xml" -UseExistingTopologyFile Run all manual steps in one single operation using the MyTopology.xml file. The topology file is not updated. .EXAMPLE PS C:\> Invoke-D365SDPInstall -Path "c:\temp\" -MetaDataDir "c:\MyRepository\Metadata" -UnifiedDevelopmentEnvironment Install the modules contained in the c:\temp\ directory into the c:\MyRepository\Metadata directory. .EXAMPLE Invoke-D365SDPInstall -Path "c:\temp\" -Command RunAll -IncludeFallbackRetailServiceModels 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. This fallback list includes the retail service models. Using default runbook id 'Runbook' and run all the operations from generate, to import to execute. .EXAMPLE Invoke-D365SDPInstall -Path "c:\temp\" -Command RunAll -ForceFallbackServiceModels 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. This fallback list does not include the retail service models. Using default runbook id 'Runbook' and run all the operations from generate, to import to execute. .NOTES Author: Tommy Skaue (@skaue) Author: Mötz Jensen (@Splaxi) Author: Florian Hopfner (@FH-Inway) Inspired by blogpost http://dev.goshoom.net/en/2016/11/installing-deployable-packages-with-powershell/ .LINK Invoke-D365SDPInstallUDE #> function Invoke-D365SDPInstall { [CmdletBinding(DefaultParameterSetName = 'QuickInstall')] param ( [Parameter(Mandatory = $True, Position = 1 )] [Alias('Hotfix')] [Alias('File')] [string] $Path, [Parameter(Mandatory = $false, Position = 2 )] [string] $MetaDataDir = "$Script:MetaDataDir", [Parameter(Mandatory = $false, ParameterSetName = 'QuickInstall', Position = 3 )] [switch] $QuickInstallAll, [Parameter(Mandatory = $false, ParameterSetName = 'DevInstall', Position = 3 )] [switch] $DevInstall, [Parameter(Mandatory = $true, ParameterSetName = 'Manual', Position = 3 )] [ValidateSet('SetTopology', 'Generate', 'Import', 'Execute', 'RunAll', 'ReRunStep', 'SetStepComplete', 'Export', 'VersionCheck')] [string] $Command = 'SetTopology', [Parameter(Mandatory = $false, Position = 4 )] [int] $Step, [Parameter(Mandatory = $false, Position = 5 )] [string] $RunbookId = "Runbook", [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\SdpInstall"), [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly, [string] $TopologyFile = "DefaultTopologyData.xml", [switch] $UseExistingTopologyFile, [Parameter(ParameterSetName = 'UDEInstall')] [switch] $UnifiedDevelopmentEnvironment, [switch] $IncludeFallbackRetailServiceModels, [switch] $Force, [switch] $ForceFallbackServiceModels ) if ($UnifiedDevelopmentEnvironment) { Invoke-D365SDPInstallUDE -Path $Path -MetaDataDir $MetaDataDir -LogPath $LogPath return } if ((Get-Process -Name "devenv" -ErrorAction SilentlyContinue).Count -gt 0) { Write-PSFMessage -Level Host -Message "It seems that you have a Visual Studio running. Please ensure exit Visual Studio and run the cmdlet again." Stop-PSFFunction -Message "Stopping because of running Visual Studio." return } Test-AssembliesLoaded if (Test-PSFFunctionInterrupt) { Write-PSFMessage -Level Host -Message "It seems that you have executed some cmdlets that required to load some Dynamics 356 Finance & Operations assemblies into memory. Please close and restart you PowerShell session / console, and start a fresh. Please note that you should execute the failed command immediately after importing the module." Stop-PSFFunction -Message "Stopping because of loaded assemblies." return } $arrRunbookIds = Get-D365Runbook -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Get-D365RunbookId if (($Command -eq "RunAll") -and ($arrRunbookIds.Runbookid -contains $RunbookId)) { Write-PSFMessage -Level Host -Message "It seems that you have entered an already used RunbookId. Please consider if you are trying to re-run some steps or simply pass another RunbookId." Stop-PSFFunction -Message "Stopping because of RunbookId already used on this machine." return } Invoke-TimeSignal -Start #Test if input is a zipFile that needs to be extracted first if ($Path.EndsWith(".zip")) { Unblock-File -Path $Path $extractedPath = $path.Remove($path.Length - 4) if (-not $Force) { if (-not (Test-PathExists -Path $extractedPath -Type Container -ShouldNotExist)) { Write-PSFMessage -Level Host -Message "The directory at the $extractedPath location already exists. If you want to override it - set the Force parameter to clear the folder and extract the content into it." Stop-PSFFunction -Message "Stopping because output path was already present." return } } Get-ChildItem -Path $extractedPath -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -Confirm:$false # To allow the file system to flush the files # Allows the human to see the folder being wiped Start-Sleep -Seconds 2 Expand-Archive -Path $Path -DestinationPath $extractedPath -Force $Path = $extractedPath } # Input is a relative path which needs to be converted to an absolute path. # see https://powershellmagazine.com/2013/01/16/pstip-check-if-the-path-is-relative-or-absolute/ if (-not ([System.IO.Path]::IsPathRooted($Path) -or (Split-Path -Path $Path -IsAbsolute))) { $currentPath = Get-Location # https://stackoverflow.com/a/13847304/2720554 $absolutePath = Join-Path -Path $currentPath -ChildPath $Path $absolutePath = [System.IO.Path]::GetFullPath($absolutePath) Write-PSFMessage -Level Verbose "Updating path to '$absolutePath' as relative paths are not supported" $Path = $absolutePath } $executable = Join-Path $Path "AXUpdateInstaller.exe" if (-not ([System.IO.Path]::IsPathRooted($TopologyFile) -or (Split-Path -Path $TopologyFile -IsAbsolute))) { $TopologyFile = Join-Path -Path $Path -ChildPath $TopologyFile } if (-not (Test-PathExists -Path $topologyFile, $executable -Type Leaf)) { return } Get-ChildItem -Path $Path -Recurse | Unblock-File if ($QuickInstallAll) { Write-PSFMessage -Level Verbose "Using QuickInstallAll mode" $params = "quickinstallall" Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath } elseif ($DevInstall) { Write-PSFMessage -Level Verbose "Using DevInstall mode" $params = "devinstall" Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath } else { $Command = $Command.ToLowerInvariant() $runbookFile = Join-Path $Path "$runbookId.xml" $serviceModelFile = Join-Path $Path 'DefaultServiceModelData.xml' if ($Command -eq 'runall') { Write-PSFMessage -Level Verbose "Running all manual steps in one single operation" #Update topology file (first command) if (-not $UseExistingTopologyFile) { $params = @{ Path = $Path TopologyFile = $TopologyFile IncludeFallbackRetailServiceModels = $IncludeFallbackRetailServiceModels ForceFallbackServiceModels = $ForceFallbackServiceModels } $ok = Update-TopologyFile @params if (-not $ok) { Write-PSFMessage -Level Warning "Failed to update topology file." return } } $params = @( "generate" "-runbookId=`"$runbookId`"" "-topologyFile=`"$topologyFile`"" "-serviceModelFile=`"$serviceModelFile`"" "-runbookFile=`"$runbookFile`"" ) #Generate (second command) Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath if (Test-PSFFunctionInterrupt) { return } $params = @( "import" "-runbookFile=`"$runbookFile`"" ) Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath if (Test-PSFFunctionInterrupt) { return } $params = @( "execute" "-runbookId=`"$runbookId`"" ) Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose "All manual steps complete." } else { $RunCommand = $true switch ($Command) { 'settopology' { Write-PSFMessage -Level Verbose "Updating topology file xml." if ($UseExistingTopologyFile) { Write-PSFMessage -Level Warning "The SetTopology command is used to update a topology file. The UseExistingTopologyFile switch should not be used with this command." return } $params = @{ Path = $Path TopologyFile = $TopologyFile IncludeFallbackRetailServiceModels = $IncludeFallbackRetailServiceModels ForceFallbackServiceModels = $ForceFallbackServiceModels } $ok = Update-TopologyFile @params if (-not $ok) { Write-PSFMessage -Level Warning "Failed to update topology file." } $RunCommand = $false } 'generate' { Write-PSFMessage -Level Verbose "Generating runbook file." $params = @( "generate" "-runbookId=`"$runbookId`"" "-topologyFile=`"$topologyFile`"" "-serviceModelFile=`"$serviceModelFile`"" "-runbookFile=`"$runbookFile`"" ) } 'import' { Write-PSFMessage -Level Verbose "Importing runbook file." $params = @( "import" "-runbookfile=`"$runbookFile`"" ) } 'execute' { Write-PSFMessage -Level Verbose "Executing runbook file." $params = @( "execute" "-runbookId=`"$runbookId`"" ) } 'rerunstep' { Write-PSFMessage -Level Verbose "Rerunning runbook step number $step." $params = @( "execute" "-runbookId=`"$runbookId`"" "-rerunstep=$step" ) } 'setstepcomplete' { Write-PSFMessage -Level Verbose "Marking step $step complete and continuing from next step." $params = @( "execute" "-runbookId=`"$runbookId`"" "-setstepcomplete=$step" ) } 'export' { Write-PSFMessage -Level Verbose "Exporting runbook for reuse." $params = @( "export" "-runbookId=`"$runbookId`"" "-runbookfile=`"$runbookFile`"" ) } 'versioncheck' { Write-PSFMessage -Level Verbose "Running version check on runbook." $params = @( "execute" "-runbookId=`"$runbookId`"" "-versioncheck=true" ) } } if ($RunCommand) { Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath if (Test-PSFFunctionInterrupt) { return } } } } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/invoke-d365sdpinstallude.ps1 ================================================  <# .SYNOPSIS Install a Software Deployable Package (SDP) in a unified development environment .DESCRIPTION A cmdlet that wraps some of the cumbersome work into a streamlined process. It first checks if the package is a zip file and extracts it if necessary. Then it checks if the package contains the necessary files and modules. Finally, it extracts the module zip files into the metadata directory. .PARAMETER Path Path to the package that you want to install into the environment The cmdlet supports a path to a zip-file or directory with the unpacked contents. .PARAMETER MetaDataDir The path to the meta data directory for the environment .PARAMETER LogPath The path where the log file(s) will be saved .PARAMETER Force Instruct the cmdlet to overwrite the "extracted" folder if it exists Used when the input is a zip file, that will auto extract to a folder named like the zip file. .EXAMPLE PS C:\> Invoke-D365SDPInstallUDE -Path "c:\temp\package.zip" -MetaDataDir "c:\MyRepository\Metadata" This will install the modules contained in the c:\temp\package.zip file into the c:\MyRepository\Metadata directory. .NOTES Author: Florian Hopfner (@FH-Inway) #> function Invoke-D365SDPInstallUDE { param ( [Parameter(Mandatory = $True, Position = 1 )] [Alias('Hotfix')] [Alias('File')] [string] $Path, [Parameter(Mandatory = $true, Position = 2 )] [string] $MetaDataDir, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\SdpInstall"), [switch] $Force ) if ((Get-Process -Name "devenv" -ErrorAction SilentlyContinue).Count -gt 0) { Write-PSFMessage -Level Host -Message "It seems that you have a Visual Studio running. Please ensure exit Visual Studio and run the cmdlet again." Stop-PSFFunction -Message "Stopping because of running Visual Studio." return } Invoke-TimeSignal -Start #Test if input is a zipFile that needs to be extracted first if ($Path.EndsWith(".zip")) { Unblock-File -Path $Path $extractedPath = $path.Remove($path.Length - 4) if (-not $Force) { if (-not (Test-PathExists -Path $extractedPath -Type Container -ShouldNotExist)) { Write-PSFMessage -Level Host -Message "The directory at the $extractedPath location already exists. If you want to override it - set the Force parameter to clear the folder and extract the content into it." Stop-PSFFunction -Message "Stopping because output path was already present." return } } Get-ChildItem -Path $extractedPath -ErrorAction SilentlyContinue | Remove-Item -Recurse -Force -Confirm:$false # To allow the file system to flush the files # Allows the human to see the folder being wiped Start-Sleep -Seconds 2 Expand-Archive -Path $Path -DestinationPath $extractedPath -Force $Path = $extractedPath } # Input is a relative path which needs to be converted to an absolute path. # see https://powershellmagazine.com/2013/01/16/pstip-check-if-the-path-is-relative-or-absolute/ if (-not ([System.IO.Path]::IsPathRooted($Path) -or (Split-Path -Path $Path -IsAbsolute))) { $currentPath = Get-Location # https://stackoverflow.com/a/13847304/2720554 $absolutePath = Join-Path -Path $currentPath -ChildPath $Path $absolutePath = [System.IO.Path]::GetFullPath($absolutePath) Write-PSFMessage -Level Verbose "Updating path to '$absolutePath' as relative paths are not supported" $Path = $absolutePath } Get-ChildItem -Path $Path -Recurse | Unblock-File $packageDetails = Get-D365SDPDetails -Path $Path $packagesFolder = "$Path\AOSService\Packages" $filesFolder = Get-ChildItem -Path $packagesFolder -Directory -Filter "files" if ($filesFolder.Count -eq 0) { Write-PSFMessage -Level Host -Message "No /AOSService/Packages/files folder found in the package. Please ensure that the package is extracted correctly." Stop-PSFFunction -Message "Stopping because of missing files folder." return } $zipFiles = Get-ChildItem -Path $filesFolder.FullName -File -Filter "*.zip" if ($zipFiles.Count -eq 0) { Write-PSFMessage -Level Host -Message "No module zip files found in the package. Please ensure that the package is extracted correctly." Stop-PSFFunction -Message "Stopping because of missing zip files." return } $numberOfInstalledModules = 0 $packageDetails.Modules | ForEach-Object { $moduleZip = $zipFiles | Where-Object Name -eq "dynamicsax-$($_.Name).$($_.Version).zip" if (-not $moduleZip) { Write-PSFMessage -Level Host -Message "No module zip file found for module $($_.Name). Please ensure that the package is extracted correctly." Stop-PSFFunction -Message "Stopping because of missing module zip file." return } # Delete existing module folder if it exists $moduleFolderPath = Join-Path -Path $MetaDataDir -ChildPath $($_.Name) if (Test-Path -Path $moduleFolderPath) { Remove-Item -Path $moduleFolderPath -Recurse -Force Write-PSFMessage -Level Verbose -Message "Deleted existing module folder $moduleFolderPath" } # Unzip to $MetaDataDir $moduleZipPath = Join-Path -Path $MetaDataDir -ChildPath $($_.Name) Expand-Archive -Path $moduleZip.FullName -DestinationPath $moduleZipPath Write-PSFMessage -Level Verbose -Message "Unzipped module $($_.Name) to $moduleZipPath" $numberOfInstalledModules++ } Write-PSFMessage -Level Host -Message "Installed $numberOfInstalledModules module(s) into $MetaDataDir" Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/invoke-d365seleniumdownload.ps1 ================================================  <# .SYNOPSIS Downloads the Selenium web driver files and deploys them to the specified destinations. .DESCRIPTION Downloads the Selenium web driver files and deploys them to the specified destinations. .PARAMETER RegressionSuiteAutomationTool Switch to specify if the Selenium files need to be installed in the Regression Suite Automation Tool folder. .PARAMETER PerfSDK Switch to specify if the Selenium files need to be installed in the PerfSDK folder. .EXAMPLE PS C:\> Invoke-D365SeleniumDownload -RegressionSuiteAutomationTool -PerfSDK This will download the Selenium zip archives and extract the files into both the Regression Suite Automation Tool folder and the PerfSDK folder. .NOTES Author: Kenny Saelen (@kennysaelen) #> function Invoke-D365SeleniumDownload { [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 0)] [switch]$RegressionSuiteAutomationTool, [Parameter(Mandatory = $false, Position = 1)] [switch]$PerfSDK ) if(!$RegressionSuiteAutomationTool -and !$PerfSDK) { Write-PSFMessage -Level Critical -Message "Either the -RegressionSuiteAutomationTool or the -PerfSDK switch needs to be specified." Stop-PSFFunction -Message "Stopping because of no switch parameters speficied." return } $seleniumDllZipLocalPath = (Join-Path $env:TEMP "selenium-dotnet-strongnamed-2.42.0.zip") $ieDriverZipLocalPath = (Join-Path $env:TEMP "IEDriverServer_Win32_2.42.0.zip") $zipExtractionPath = (Join-Path $env:TEMP "D365Seleniumextraction") try { Write-PSFMessage -Level Host -Message "Downloading Selenium files" $WebClient = New-Object System.Net.WebClient $WebClient.DownloadFile("http://selenium-release.storage.googleapis.com/2.42/selenium-dotnet-strongnamed-2.42.0.zip", $seleniumDllZipLocalPath) $WebClient.DownloadFile("http://selenium-release.storage.googleapis.com/2.42/IEDriverServer_Win32_2.42.0.zip", $ieDriverZipLocalPath) Write-PSFMessage -Level Host -Message "Extracting zip files" Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::ExtractToDirectory($seleniumDllZipLocalPath, $zipExtractionPath) [System.IO.Compression.ZipFile]::ExtractToDirectory($ieDriverZipLocalPath, $zipExtractionPath) $targetPath = [String]::Empty $seleniumPath = [String]::Empty if($RegressionSuiteAutomationTool) { Write-PSFMessage -Level Host -Message "Making Selenium folder structure in the Regression Suite Automation Tool folder" $targetPath = Join-Path ([Environment]::GetEnvironmentVariable("ProgramFiles(x86)")) "Regression Suite Automation Tool" $seleniumPath = Join-Path $targetPath "Common\External\Selenium" # Check if the Regression Suite Automation Tool is installed on the machine and Selenium not already installed if (Test-PathExists -Path $targetPath -Type Container) { if(-not(Test-PathExists -Path $seleniumPath -Type Container -Create)) { Write-PSFMessage -Level Critical -Message [String]::Format("The folder for the Selenium files could not be created: {0}", $seleniumPath) } Write-PSFMessage -Level Host -Message "Copying Selenium files to destination folder" Copy-Item (Join-Path $zipExtractionPath "IEDriverServer.exe") $seleniumPath Copy-Item (Join-Path $zipExtractionPath "net40\*") $seleniumPath Write-PSFMessage -Level Host -Message ([String]::Format("Selenium files have been downloaded and installed in the following folder: {0}", $seleniumPath)) } else { 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) } } if($PerfSDK) { Write-PSFMessage -Level Host -Message "Making Selenium folder structure in the PerfSDK folder" $targetPath = [Environment]::GetEnvironmentVariable("PerfSDK") $seleniumPath = Join-Path $targetPath "Common\External\Selenium" # Check if the PerfSDK is installed on the machine and Selenium not already installed if (Test-PathExists -Path $targetPath -Type Container) { if(-not(Test-PathExists -Path $seleniumPath -Type Container -Create)) { Write-PSFMessage -Level Critical -Message [String]::Format("The folder for the Selenium files could not be created: {0}", $seleniumPath) } Write-PSFMessage -Level Host -Message "Copying Selenium files to destination folder" Copy-Item (Join-Path $zipExtractionPath "IEDriverServer.exe") $seleniumPath Copy-Item (Join-Path $zipExtractionPath "net40\*") $seleniumPath Write-PSFMessage -Level Host -Message ([String]::Format("Selenium files have been downloaded and installed in the following folder: {0}", $seleniumPath)) } else { 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) } } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while downloading and installing the Selenium files." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { Write-PSFMessage -Level Host -Message "Cleaning up temporary files" Remove-Item -Path $seleniumDllZipLocalPath -Recurse Remove-Item -Path $ieDriverZipLocalPath -Recurse Remove-Item -Path $zipExtractionPath -Recurse } } ================================================ FILE: d365fo.tools/functions/invoke-d365sqlscript.ps1 ================================================  <# .SYNOPSIS Execute a SQL Script or a SQL Command .DESCRIPTION Execute a SQL Script or a SQL Command against the D365FO SQL Server database .PARAMETER FilePath Path to the file containing the SQL Script that you want executed .PARAMETER Command SQL command that you want executed .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER TrustedConnection Switch to instruct the cmdlet whether the connection should be using Windows Authentication or not .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .PARAMETER NoPooling Should the connection use connection pooling or not .EXAMPLE PS C:\> Invoke-D365SqlScript -FilePath "C:\temp\d365fo.tools\DeleteUser.sql" This will execute the "C:\temp\d365fo.tools\DeleteUser.sql" against the registered SQL Server on the machine. .EXAMPLE PS C:\> Invoke-D365SqlScript -Command "DELETE FROM SALESTABLE WHERE RECID = 123456789" This will execute "DELETE FROM SALESTABLE WHERE RECID = 123456789" against the registered SQL Server on the machine. .EXAMPLE PS C:\> Invoke-D365SqlScript -Command "DELETE FROM SALESTABLE WHERE RECID = 123456789" -NoPooling This will execute "DELETE FROM SALESTABLE WHERE RECID = 123456789" against the registered SQL Server on the machine. It will not use connection pooling. .NOTES Author: Mötz Jensen (@splaxi) Author: Caleb Blanchard (@daxcaleb) #> Function Invoke-D365SqlScript { [Alias("Invoke-D365SqlCmd")] [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "FilePath" )] [string] $FilePath, [Parameter(Mandatory = $true, Position = 1, ParameterSetName = "Command" )] [string] $Command, [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword, [bool] $TrustedConnection = $false, [switch] $EnableException, [switch] $NoPooling ) if ($PSCmdlet.ParameterSetName -eq "FilePath") { if (-not (Test-PathExists -Path $FilePath -Type Leaf)) { return } } Invoke-TimeSignal -Start $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $Params = @{} #Hack to get all variables for the function, regardless of they were assigned from the caller or with default values. #The TrustedConnection is the real deal breaker. If $true user and password are ignored in Get-SqlCommand. $MyInvocation.MyCommand.Parameters.Keys | Get-Variable -ErrorAction Ignore | ForEach-Object { $Params.Add($_.Name, $_.Value) }; $null = $Params.Remove('FilePath') $null = $Params.Remove('Command') $null = $Params.Remove('EnableException') $Params.TrustedConnection = $UseTrustedConnection $sqlCommand = Get-SqlCommand @Params if ($PSCmdlet.ParameterSetName -eq "FilePath") { $sqlCommand.CommandText = (Get-Content "$FilePath") -join [Environment]::NewLine } if ($PSCmdlet.ParameterSetName -eq "Command") { $sqlCommand.CommandText = $Command } try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $null = $sqlCommand.ExecuteNonQuery() } catch { $messageString = "Something went wrong while executing custom sql script against the database." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ -StepsUpward 1 return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/invoke-d365sysflushaodcache.ps1 ================================================  <# .SYNOPSIS Invoke the SysFlushAos class .DESCRIPTION Invoke the runnable class SysFlushAos to clear the AOD cache .PARAMETER URL URL to the Dynamics 365 instance you want to clear the AOD cache on .EXAMPLE PS C:\> Invoke-D365SysFlushAodCache This will a call against the default URL for the machine and have it execute the SysFlushAOD class .NOTES Author: Mötz Jensen (@Splaxi) #> function Invoke-D365SysFlushAodCache { [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 1 )] [string] $Url ) if ($PSBoundParameters.ContainsKey("URL")) { Invoke-D365SysRunnerClass -ClassName "SysFlushAOD" -Url $URL } else { Invoke-D365SysRunnerClass -ClassName "SysFlushAOD" } } ================================================ FILE: d365fo.tools/functions/invoke-d365sysrunnerclass.ps1 ================================================  <# .SYNOPSIS Start a browser session that executes SysRunnerClass .DESCRIPTION Makes it possible to call any runnable class directly from the browser, without worrying about the details .PARAMETER ClassName The name of the class you want to execute .PARAMETER Company The company for which you want to execute the class against Default value is: "DAT" .PARAMETER Url The URL you want to execute against Default value is the Fully Qualified Domain Name registered on the machine .EXAMPLE PS C:\> Invoke-D365SysRunnerClass -ClassName SysFlushAOD Will execute the SysRunnerClass and have it execute the SysFlushAOD class and will run it against the "DAT" (default value) company .EXAMPLE PS C:\> Invoke-D365SysRunnerClass -ClassName SysFlushAOD -Company "USMF" Will execute the SysRunnerClass and have it execute the SysFlushAOD class and will run it against the "USMF" company .EXAMPLE PS C:\> Invoke-D365SysRunnerClass -ClassName SysFlushAOD -Url https://Test.cloud.onebox.dynamics.com 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 .NOTES Author: Mötz Jensen (@Splaxi) #> function Invoke-D365SysRunnerClass { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 1 )] [string] $ClassName, [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )] [string] $Company = $Script:Company, [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 3 )] [string] $Url = $Script:Url ) $executingUrl = "$Url`?cmp=$Company&mi=SysClassRunner&cls=$ClassName" Start-Process $executingUrl } ================================================ FILE: d365fo.tools/functions/invoke-d365tablebrowser.ps1 ================================================  <# .SYNOPSIS Start a browser session that will show the table browser .DESCRIPTION Makes it possible to call the table browser for a given table directly from the web browser, without worrying about the details .PARAMETER TableName The name of the table you want to see the rows for .PARAMETER Company The company for which you want to see the data from in the given table Default value is: "DAT" .PARAMETER Url The URL you want to execute against Default value is the Fully Qualified Domain Name registered on the machine .EXAMPLE PS C:\> Invoke-D365TableBrowser -TableName SalesTable Will open the table browser and show all the records in Sales Table from the "DAT" company (default value). .EXAMPLE PS C:\> Invoke-D365TableBrowser -TableName SalesTable -Company "USMF" Will open the table browser and show all the records in Sales Table from the "USMF" company. .NOTES Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. #> function Invoke-D365TableBrowser { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $true, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 1 )] [string] $TableName, [Parameter(Mandatory = $false, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 2 )] [string] $Company = $Script:Company, [Parameter(Mandatory = $false, ParameterSetName = 'Default', ValueFromPipelineByPropertyName = $true, Position = 3 )] [string] $Url = $Script:Url ) BEGIN {} PROCESS { Write-PSFMessage -Level Verbose -Message "Table name: $TableName" -Target $TableName $executingUrl = "$Url`?cmp=$Company&mi=SysTableBrowser&tablename=$TableName" Start-Process $executingUrl #* Allow the browser to start and process first request if it isn't running already Start-Sleep -Seconds 1 } END {} } ================================================ FILE: d365fo.tools/functions/invoke-d365visualstudiocompilerresultanalyzer.ps1 ================================================  <# .SYNOPSIS Analyze the Visual Studio compiler output log .DESCRIPTION Analyze the Visual Studio compiler output log and generate an excel file contain worksheets per type: Errors, Warnings, Tasks .PARAMETER Module Name of the module that you want to work against Default value is "*" which will search for all modules .PARAMETER OutputPath Path where you want the excel file (xlsx-file) saved to Default value is: "c:\temp\d365fo.tools\" .PARAMETER SkipWarnings Instructs the cmdlet to skip warnings while analyzing the compiler output log file .PARAMETER SkipTasks Instructs the cmdlet to skip tasks while analyzing the compiler output log file .PARAMETER PackageDirectory Path to the directory containing the installed package / module Default path is the same as the AOS service "PackagesLocalDirectory" directory Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Invoke-D365VisualStudioCompilerResultAnalyzer This will analyse all compiler output log files generated from Visual Studio. A result set example: File Filename ---- -------- c:\temp\d365fo.tools\ApplicationCommon-CompilerResults.xlsx ApplicationCommon-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationFoundation-CompilerResults.xlsx ApplicationFoundation-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationPlatform-CompilerResults.xlsx ApplicationPlatform-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationSuite-CompilerResults.xlsx ApplicationSuite-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationWorkspaces-CompilerResults.xlsx ApplicationWorkspaces-CompilerResults.xlsx .EXAMPLE PS C:\> Invoke-D365VisualStudioCompilerResultAnalyzer -SkipWarnings This will analyse all compiler output log files generated from Visual Studio. It will exclude all warnings from the output. A result set example: File Filename ---- -------- c:\temp\d365fo.tools\ApplicationCommon-CompilerResults.xlsx ApplicationCommon-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationFoundation-CompilerResults.xlsx ApplicationFoundation-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationPlatform-CompilerResults.xlsx ApplicationPlatform-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationSuite-CompilerResults.xlsx ApplicationSuite-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationWorkspaces-CompilerResults.xlsx ApplicationWorkspaces-CompilerResults.xlsx .EXAMPLE PS C:\> Invoke-D365VisualStudioCompilerResultAnalyzer -SkipTasks This will analyse all compiler output log files generated from Visual Studio. It will exclude all tasks from the output. A result set example: File Filename ---- -------- c:\temp\d365fo.tools\ApplicationCommon-CompilerResults.xlsx ApplicationCommon-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationFoundation-CompilerResults.xlsx ApplicationFoundation-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationPlatform-CompilerResults.xlsx ApplicationPlatform-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationSuite-CompilerResults.xlsx ApplicationSuite-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationWorkspaces-CompilerResults.xlsx ApplicationWorkspaces-CompilerResults.xlsx .NOTES Tags: Compiler, Build, Errors, Warnings, Tasks Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Vilmos Kintera" (twitter: @DAXRunBase) All credits goes to him for showing how to extract these information His blog can be found here: https://www.daxrunbase.com/blog/ The specific blog post that we based this cmdlet on can be found here: https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/ The github repository containing the original scrips can be found here: https://github.com/DAXRunBase/PowerShell-and-Azure #> function Invoke-D365VisualStudioCompilerResultAnalyzer { [CmdletBinding()] [OutputType('')] param ( [Alias("ModuleName")] [string] $Module = "*", [string] $OutputPath = $Script:DefaultTempPath, [switch] $SkipWarnings, [switch] $SkipTasks, [string] $PackageDirectory = $Script:PackageDirectory ) Invoke-TimeSignal -Start if (-not (Test-PathExists -Path $PackageDirectory -Type Container)) { return } $buildOutputFiles = Get-ChildItem -Path "$PackageDirectory\$Module\BuildModelResult.log" -ErrorAction SilentlyContinue -Force foreach ($result in $buildOutputFiles) { $moduleName = Split-Path -Path $result.DirectoryName -Leaf $outputFilePath = Join-Path -Path $OutputPath -ChildPath "$moduleName-CompilerResults.xlsx" Invoke-CompilerResultAnalyzer -Path $result.FullName -Identifier $moduleName -OutputPath $outputFilePath -SkipWarnings:$SkipWarnings -SkipTasks:$SkipTasks -PackageDirectory $PackageDirectory } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/invoke-d365winrmcertificaterotation.ps1 ================================================  <# .SYNOPSIS Rotate the certificate used for WinRM .DESCRIPTION There is a scenario where you might need to update the certificate that is being used for WinRM on your Tier1 environment 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 .PARAMETER MachineName The DNS / Netbios name of the machine The default value is: "$env:COMPUTERNAME" which translates into the current name of the machine .EXAMPLE PS C:\> Invoke-D365WinRmCertificateRotation This will update the certificate that is being used by WinRM. A new certificate is created with the current computer name. The new certificate and its thumbprint will be configured for WinRM to use that going forward. .NOTES Author: Mötz Jensen (@Splaxi) We recommend that you do a full restart of the Tier1 environment when done. #> function Invoke-D365WinRmCertificateRotation { [CmdletBinding()] [OutputType()] param( [string] $MachineName = $env:COMPUTERNAME ) Write-PSFMessage -Level Verbose "Creating a new certificate." $CertStore = "Cert:\LocalMachine\My" $Thumbprint = (New-SelfSignedCertificate -DnsName $MachineName -CertStoreLocation $CertStore).Thumbprint $executable = "C:\Windows\System32\cmd.exe" $params = @("/C", "winrm", "set", "winrm/config/Listener?Address=*+Transport=HTTPS", "@{Hostname=""$DNSName""; CertificateThumbprint=""$Thumbprint""}" ) Write-PSFMessage -Level Verbose "Configure WinRM to use the newly created certificate." Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$true } ================================================ FILE: d365fo.tools/functions/new-d365bacpac.ps1 ================================================  <# .SYNOPSIS Generate a bacpac file from a database .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 Supports to create a raw bacpac file without prepping. Can be used to automate backup from Tier 2 (MS hosted) environment .PARAMETER ExportModeTier1 Switch to instruct the cmdlet that the export will be done against a classic SQL Server installation .PARAMETER ExportModeTier2 Switch to instruct the cmdlet that the export will be done against an Azure SQL DB instance .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER BackupDirectory The path where to store the temporary backup file when the script needs to handle that .PARAMETER NewDatabaseName The name for the database the script is going to create when doing the restore process .PARAMETER BacpacFile The path where you want the cmdlet to store the bacpac file that will be generated .PARAMETER CustomSqlFile The path to a custom sql server script file that you want executed against the database before it is exported .PARAMETER DiagnosticFile Path to where you want the export to output a diagnostics file to assist you in troubleshooting the export .PARAMETER ExportOnly Switch to instruct the cmdlet to either just create a dump bacpac file or run the prepping process first .PARAMETER MaxParallelism Sets SqlPackage.exe's degree of parallelism for concurrent operations running against a database. The default value is 8. .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Invoke-D365InstallSqlPackage You should always install the latest version of the SqlPackage.exe, which is used by New-D365Bacpac. This will fetch the latest .Net Core Version of SqlPackage.exe and install it at "C:\temp\d365fo.tools\SqlPackage". .EXAMPLE PS C:\> New-D365Bacpac -ExportModeTier1 -BackupDirectory c:\Temp\backup\ -NewDatabaseName Testing1 -BacpacFile "C:\Temp\Bacpac\Testing1.bacpac" Will backup the "AXDB" database and restore is as "Testing1" again the localhost SQL Server. Will run the prepping process against the restored database. Will export a bacpac file to "C:\Temp\Bacpac\Testing1.bacpac". Will delete the restored database. It will use trusted connection (Windows authentication) while working against the SQL Server. .EXAMPLE PS C:\> New-D365Bacpac -ExportModeTier2 -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" -NewDatabaseName Testing1 -BacpacFile C:\Temp\Bacpac\Testing1.bacpac Will create a copy the db database on the dbserver1 in Azure. Will run the prepping process against the copy database. Will export a bacpac file. Will delete the copy database. .EXAMPLE PS C:\> New-D365Bacpac -ExportModeTier2 -SqlUser User123 -SqlPwd "Password123" -NewDatabaseName Testing1 -BacpacFile "C:\Temp\Bacpac\Testing1.bacpac" Normally used for a Tier-2 export and preparation for Tier-1 import Will create a copy of the registered D365 database on the registered D365 Azure SQL DB instance. Will run the prepping process against the copy database. Will export a bacpac file. Will delete the copy database. .EXAMPLE PS C:\> New-D365Bacpac -ExportModeTier2 -SqlUser User123 -SqlPwd "Password123" -NewDatabaseName Testing1 -BacpacFile C:\Temp\Bacpac\Testing1.bacpac -ExportOnly Will export a bacpac file. The bacpac should be able to restore back into the database without any preparing because it is coming from the environment from the beginning .EXAMPLE PS C:\> New-D365Bacpac -ExportModeTier1 -BackupDirectory c:\Temp\backup\ -NewDatabaseName Testing1 -BacpacFile "C:\Temp\Bacpac\Testing1.bacpac" -DiagnosticFile "C:\temp\ExportLog.txt" Will backup the "AXDB" database and restore is as "Testing1" again the localhost SQL Server. Will run the prepping process against the restored database. Will export a bacpac file to "C:\Temp\Bacpac\Testing1.bacpac". Will delete the restored database. It will use trusted connection (Windows authentication) while working against the SQL Server. It will output a diagnostic file to "C:\temp\ExportLog.txt". .EXAMPLE PS C:\> New-D365Bacpac -ExportModeTier1 -BackupDirectory c:\Temp\backup\ -NewDatabaseName Testing1 -BacpacFile "C:\Temp\Bacpac\Testing1.bacpac" -MaxParallelism 32 Will backup the "AXDB" database and restore is as "Testing1" again the localhost SQL Server. Will run the prepping process against the restored database. Will export a bacpac file to "C:\Temp\Bacpac\Testing1.bacpac". Will delete the restored database. It will use trusted connection (Windows authentication) while working against the SQL Server. It will use 32 connections against the database server while generating the bacpac file. .NOTES The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function New-D365Bacpac { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseProcessBlockForPipelineCommand", "")] [CmdletBinding(DefaultParameterSetName = 'ExportTier2')] param ( [Parameter(Mandatory = $true, ParameterSetName = 'ExportTier1', Position = 0)] [switch] $ExportModeTier1, [Parameter(Mandatory = $true, ParameterSetName = 'ExportTier2', Position = 0)] [switch] $ExportModeTier2, [Parameter(Position = 1 )] [string] $DatabaseServer = $Script:DatabaseServer, [Parameter(Position = 2 )] [string] $DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, Position = 3 )] [Parameter(Mandatory = $true, ParameterSetName = 'ExportTier2', ValueFromPipelineByPropertyName = $true, Position = 3)] [string] $SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, Position = 4 )] [Parameter(Mandatory = $true, ParameterSetName = 'ExportTier2', ValueFromPipelineByPropertyName = $true, Position = 4)] [string] $SqlPwd = $Script:DatabaseUserPassword, [Parameter(ParameterSetName = 'ExportTier1', Position = 5 )] [string] $BackupDirectory = "C:\Temp\d365fo.tools\SqlBackups", [Parameter(Position = 6 )] [string] $NewDatabaseName = "$Script:DatabaseName`_export", [Parameter(Position = 7 )] [Alias('File')] [string] $BacpacFile = "C:\Temp\d365fo.tools\$DatabaseName.bacpac", [Parameter(Position = 8 )] [string] $CustomSqlFile, [string] $DiagnosticFile, [switch] $ExportOnly, [int] $MaxParallelism = 8, [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly, [switch] $EnableException ) Invoke-TimeSignal -Start $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters if ($PSBoundParameters.ContainsKey("CustomSqlFile")) { if (-not (Test-PathExists -Path $CustomSqlFile -Type Leaf)) { return } $ExecuteCustomSQL = $true } if ($BacpacFile -notlike "*.bacpac") { Write-PSFMessage -Level Host -Message "The path for the bacpac file must contain the .bacpac extension. Please update the BacpacFile parameter and try again." Stop-PSFFunction -Message "The BacpacFile path was not correct." return } if ($PSBoundParameters.ContainsKey("BackupDirectory") -or $ExportModeTier1) { if (-not (Test-PathExists -Path $BackupDirectory -Type Container -Create)) { return } } if (-not (Test-PathExists -Path (Split-Path $BacpacFile -Parent) -Type Container -Create)) { return } # Work around to make sure to keep Storage when using the non-core version of the SqlPackage $executable = $Script:SqlPackagePath $classicPattern = "C:\Program Files*\Microsoft SQL Server\1*0\DAC\bin\SqlPackage.exe" [System.Collections.ArrayList] $Properties = New-Object -TypeName "System.Collections.ArrayList" $null = $Properties.Add("VerifyFullTextDocumentTypesSupported=false") if($executable -like $classicPattern) { 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." $null = $Properties.Add("Storage=File") } $BaseParams = @{ DatabaseServer = $DatabaseServer DatabaseName = $DatabaseName SqlUser = $SqlUser SqlPwd = $SqlPwd } $ExportParams = @{ Action = "export" FilePath = $BacpacFile Properties = $Properties.ToArray() MaxParallelism = $MaxParallelism } if (-not [system.string]::IsNullOrEmpty($DiagnosticFile)) { if (-not (Test-PathExists -Path (Split-Path $DiagnosticFile -Parent) -Type Container -Create)) { return } $ExportParams.DiagnosticFile = $DiagnosticFile } if ($ExportOnly) { Write-PSFMessage -Level Verbose -Message "Invoking the export of the bacpac file only." Write-PSFMessage -Level Verbose -Message "Invoking the sqlpackage with parameters" -Target $BaseParams Invoke-SqlPackage @BaseParams @ExportParams -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly if ($OutputCommandOnly) { return } if (Test-PSFFunctionInterrupt) { return } [PSCustomObject]@{ File = $BacpacFile Filename = (Split-Path $BacpacFile -Leaf) } } else { if ($ExportModeTier1) { $Params = @{ BackupDirectory = $BackupDirectory NewDatabaseName = $NewDatabaseName TrustedConnection = $UseTrustedConnection } if (-not $OutputCommandOnly) { Write-PSFMessage -Level Verbose -Message "Invoking the Tier 1 - SQL backup & restore process" $res = Invoke-SqlBackupRestore @BaseParams @Params if ((Test-PSFFunctionInterrupt) -or (-not $res)) { return } $Params = Get-DeepClone $BaseParams $Params.DatabaseName = $NewDatabaseName Write-PSFMessage -Level Verbose -Message "Invoking the Tier 1 - Clear SQL objects" $res = Invoke-ClearSqlSpecificObjects @Params if ((Test-PSFFunctionInterrupt) -or (-not $res)) { return } if ($ExecuteCustomSQL) { Write-PSFMessage -Level Verbose -Message "Invoking the Tier 1 - Execution of custom SQL script" $res = Invoke-D365SqlScript @Params -FilePath $CustomSqlFile if (Test-PSFFunctionInterrupt) { return } } } else { $Params = Get-DeepClone $BaseParams $Params.DatabaseName = $NewDatabaseName } Write-PSFMessage -Level Verbose -Message "Invoking the Tier 1 - Export of the bacpac file from SQL" Invoke-SqlPackage @Params @ExportParams -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly if ($OutputCommandOnly) { return } if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Invoking the Tier 1 - Remove database from SQL" Remove-D365Database @Params -Confirm:$false [PSCustomObject]@{ File = $BacpacFile Filename = (Split-Path $BacpacFile -Leaf) } } else { $Params = @{ NewDatabaseName = $NewDatabaseName } if (-not $OutputCommandOnly) { Write-PSFMessage -Level Verbose -Message "Invoking the Tier 2 - Creation of Azure DB copy" $res = Invoke-AzureBackupRestore @BaseParams @Params if ((Test-PSFFunctionInterrupt) -or (-not $res)) { return } $Params = Get-DeepClone $BaseParams $Params.DatabaseName = $NewDatabaseName Write-PSFMessage -Level Verbose -Message "Invoking the Tier 2 - Clear Azure DB objects" $res = Invoke-ClearAzureSpecificObjects @Params if ((Test-PSFFunctionInterrupt) -or (-not $res)) { return } if ($ExecuteCustomSQL) { Write-PSFMessage -Level Verbose -Message "Invoking the Tier 2 - Execution of custom SQL script" $res = Invoke-D365SqlScript @Params -FilePath $CustomSqlFile -TrustedConnection $false if (!$res) { return } } } Write-PSFMessage -Level Verbose -Message "Invoking the Tier 2 - Export of the bacpac file from Azure DB" Invoke-SqlPackage @Params @ExportParams -TrustedConnection $false -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly if ($OutputCommandOnly) { return } if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Invoking the Tier 2 - Remove database from Azure DB" Remove-D365Database @Params -Confirm:$false if (Test-PSFFunctionInterrupt) { $messageString = "The bacpac file was created correctly, but there was an error while removing the cloned database." Write-PSFMessage -Level Host -Message $messageString } [PSCustomObject]@{ File = $BacpacFile Filename = (Split-Path $BacpacFile -Leaf) } } } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/new-d365careport.ps1 ================================================  <# .SYNOPSIS Generate the Customization's Analysis Report (CAR) .DESCRIPTION A cmdlet that wraps some of the cumbersome work into a streamlined process .PARAMETER OutputPath Path where you want the CAR file (xlsx-file) saved to Default value is: "c:\temp\d365fo.tools\CAReport.xlsx" .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin .PARAMETER MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory .PARAMETER Module Name of the Module to analyse .PARAMETER Model Name of the Model to analyse .PARAMETER XmlLog Path where you want to store the Xml log output generated from the best practice analyser .PARAMETER PackagesRoot Instructs the cmdlet to use binary metadata .PARAMETER LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .PARAMETER SuffixWithModule Instruct the cmdlet to append the module name as a suffix to the desired output file name .EXAMPLE PS C:\> New-D365CAReport -module "ApplicationSuite" -model "MyOverLayerModel" This will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module. It will use the default value for the OutputPath parameter, which is "c:\temp\d365fo.tools\CAReport.xlsx". .EXAMPLE PS C:\> New-D365CAReport -OutputPath "c:\temp\CAReport.xlsx" -module "ApplicationSuite" -model "MyOverLayerModel" This will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module. It will use the "c:\temp\CAReport.xlsx" value for the OutputPath parameter. .EXAMPLE PS C:\> New-D365CAReport -module "ApplicationSuite" -model "MyOverLayerModel" -SuffixWithModule This will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module. It will use the default value for the OutputPath parameter, which is "c:\temp\d365fo.tools\CAReport.xlsx". It will append the module name to the desired output file, which will then be "c:\temp\d365fo.tools\CAReport-ApplicationSuite.xlsx". .EXAMPLE PS C:\> New-D365CAReport -OutputPath "c:\temp\CAReport.xlsx" -module "ApplicationSuite" -model "MyOverLayerModel" -PackagesRoot This will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module. It will use the binary metadata to look for the module and model. It will use the "c:\temp\CAReport.xlsx" value for the OutputPath parameter. .NOTES Author: Tommy Skaue (@Skaue) Author: Mötz Jensen (@Splaxi) #> function New-D365CAReport { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] [CmdletBinding()] param ( [Alias('File')] [Alias('Path')] [string] $OutputPath = (Join-Path $Script:DefaultTempPath "CAReport.xlsx"), [Parameter(Mandatory = $true)] [Alias('Package')] [Alias("ModuleName")] [string] $Module, [Parameter(Mandatory = $true)] [string] $Model, [switch] $SuffixWithModule, [string] $BinDir = "$Script:PackageDirectory\bin", [string] $MetaDataDir = "$Script:MetaDataDir", [string] $XmlLog = (Join-Path $Script:DefaultTempPath "BPCheckLogcd.xml"), [switch] $PackagesRoot, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\CAReport"), [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { return } $executable = Join-Path $BinDir "xppbp.exe" if (-not (Test-PathExists -Path $executable -Type Leaf)) { return } if ($SuffixWithModule) { $OutputPath = $OutputPath.Replace(".xlsx", "-$Module.xlsx") } $params = @( "-metadata=`"$MetaDataDir`"", "-all", "-module=`"$Module`"", "-model=`"$Model`"", "-xmlLog=`"$XmlLog`"", "-car=`"$OutputPath`"" ) if ($PackagesRoot -eq $true) { $params += "-packagesroot=`"$MetaDataDir`"" } Write-PSFMessage -Level Verbose -Message "Starting the $executable with the parameter options." -Target $param Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath if (Test-PSFFunctionInterrupt) { return } [PSCustomObject]@{ File = $OutputPath Filename = (Split-Path $OutputPath -Leaf) } } ================================================ FILE: d365fo.tools/functions/new-d365entraintegration.ps1 ================================================  <# .SYNOPSIS Enable the Microsoft Entra ID integration on a cloud hosted environment (CHE). .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. The integration can either be enabled with an existing certificate or a new self-signed certificate can be created. 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. The steps executed are: - 1) Create a self-signed certificate and save it to Desktop or use a provided certificate. - 2) Install the certificate to the "LocalMachine" certificate store. - 3) Grant NetworkService READ permission to the certificate (only on cloud-hosted environments). - 4) Update the web.config with the application ID and the thumbprint of the certificate. - 5) Add the application registration to the WIF config. - 6) Clear cached LCS configuration in AxDB. - 7) Restart the IIS service. To execute the steps, the id of an Azure application must be provided. The application must have the following API permissions: - Dynamics ERP - This permission is required to access finance and operations environments. - Microsoft Graph (User.Read.All and Group.Read.All permissions of the Application type). - Dynamics Lifecylce service (permission of type Delegated) The URL of the finance and operations environment must also be added to the RedirectURI in the Authentication section of the Azure application. Finally, after running the cmdlet, if a new certificate was created, it must be uploaded to the Azure application. .PARAMETER ClientId The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal. It is assumed that an application with this id already exists in Azure. .PARAMETER ExistingCertificateFile The path to a certificate file. If this parameter is provided, the cmdlet will not create a new certificate. .PARAMETER ExistingCertificatePrivateKeyFile The path to a certificate private key file. If this parameter is not provided, the certificate can be installed to the certificate store, but the NetworkService cannot be granted READ permission. .PARAMETER CertificateName The name for the certificate. By default, it is named "CHEAuth". .PARAMETER CertificateExpirationYears The number of years the certificate is valid. By default, it is valid for 2 years. .PARAMETER NewCertificateFile The path to the certificate file that will be created. By default, it is created on the Desktop of the current user. .PARAMETER NewCertificatePrivateKeyFile The path to the certificate private key file that will be created. By default, it is created on the Desktop of the current user. .PARAMETER CertificatePassword The password for the certificate private key file. If not provided when creating a new certificate, no private key file will be created. If not provided when using an existing certificate, the private key file cannot be installed. .PARAMETER Force 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. .PARAMETER WhatIf Executes the cmdlet until the first operation that would change the state of the system, without executing that operation. Subsequent operations are likely to fail. This is currently not fully implemented and should not be used. .PARAMETER Confirm Prompts for confirmation before each operation of the cmdlet that changes the state of the system. .OUTPUTS If a new certificate is created, the certificate file is placed on the Desktop of the current user. It must be uploaded to the Azure Application. .EXAMPLE PS C:\> New-D365EntraIntegration -ClientId e70cac82-6a7c-4f9e-a8b9-e707b961e986 Enables the Entra ID integration with a new self-signed certificate named "CHEAuth" which expires after 2 years. .EXAMPLE PS C:\> New-D365EntraIntegration -ClientId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -CertificateName "SelfsignedCert" Enables the Entra ID integration with a new self-signed certificate with the name "Selfsignedcert" that expires after 2 years. .EXAMPLE PS C:\> New-D365EntraIntegration -AppId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -CertificateName "SelfsignedCert" -CertificateExpirationYears 1 Enables the Entra ID integration with a new self-signed certificate with the name "SelfsignedCert" that expires after 1 year. .EXAMPLE PS C:\> $securePassword = Read-Host -AsSecureString -Prompt "Enter the certificate password" PS C:\> New-D365EntraIntegration -AppId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -CertificatePassword $securePassword 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. The certificate file and the private key file are saved to the Desktop of the current user. .EXAMPLE PS C:\> $securePassword = Read-Host -AsSecureString -Prompt "Enter the certificate password" PS C:\> New-D365EntraIntegration -AppId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -ExistingCertificateFile "C:\Temp\SelfsignedCert.cer" -ExistingCertificatePrivateKeyFile "C:\Temp\SelfsignedCert.pfx" -CertificatePassword $securePassword 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. .NOTES Test-D365EntraIntegration can be used to validate an entra integration. Author: Øystein Brenna (@oysbre) Author: Florian Hopfner (@FH-Inway) #> function New-D365EntraIntegration { [CmdletBinding( DefaultParameterSetName = "NewCertificate", SupportsShouldProcess)] param ( [Parameter(Mandatory = $true)] [Alias("AppId")] [string] $ClientId, [Parameter(Mandatory = $true, ParameterSetName = "ExistingCertificate")] [string] $ExistingCertificateFile, [Parameter(ParameterSetName = "ExistingCertificate")] [string] $ExistingCertificatePrivateKeyFile, [Parameter(ParameterSetName = "NewCertificate")] [string]$CertificateName = "CHEAuth", [Parameter(ParameterSetName = "NewCertificate")] [int]$CertificateExpirationYears = 2, [Parameter(ParameterSetName = "NewCertificate")] [string] $NewCertificateFile = "$env:USERPROFILE\Desktop\$CertificateName.cer", [Parameter(ParameterSetName = "NewCertificate")] [string] $NewCertificatePrivateKeyFile = "$env:USERPROFILE\Desktop\$CertificateName.pfx", [Security.SecureString] $CertificatePassword, [switch] $Force ) if (-not ($Script:IsAdminRuntime)) { Write-PSFMessage -Level Critical -Message "It seems that you ran this cmdlet non-elevated. 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`"" Stop-PSFFunction -Message "Stopping because the function is not run elevated" return } $certificateStoreLocation = "Cert:\LocalMachine\My" $certificateThumbprint = "" # Steps 1 and 2: Create or use existing certificate and install it to the certificate store # Check and install provided certificate file if ($PSCmdlet.ParameterSetName -eq "ExistingCertificate") { Write-PSFMessage -Level Verbose -Message "Steps 1+2: Starting installation of existing certificate" $params = @{ CertificateFile = $ExistingCertificateFile PrivateKeyFile = $ExistingCertificatePrivateKeyFile CertificatePassword = $CertificatePassword Force = $Force } $certificateThumbprint = CheckAndInstallExistingCertificate @params } # Create and install new certificate if ($PSCmdlet.ParameterSetName -eq "NewCertificate") { Write-PSFMessage -Level Verbose -Message "Steps 1+2: Starting creation of new certificate" $params = @{ CertificateName = $CertificateName CertificateExpirationYears = $CertificateExpirationYears NewCertificateFile = $NewCertificateFile NewCertificatePrivateKeyFile = $NewCertificatePrivateKeyFile CertificatePassword = $CertificatePassword Force = $Force } $certificateThumbprint = CreateAndInstallNewCertificate @params } # Sanity checks before next steps if (Test-PSFFunctionInterrupt) { return } if (-not $certificateThumbprint) { Write-PSFMessage -Level Host -Message "Unable to get the certificate thumbprint." Stop-PSFFunction -Message "Stopping because the certificate thumbprint could not be retrieved" return } $certificateObject = Get-ChildItem $certificateStoreLocation | Where-Object Thumbprint -eq $certificateThumbprint if (-not $certificateObject) { Write-PSFMessage -Level Host -Message "Unable to get the certificate object." Stop-PSFFunction -Message "Stopping because the certificate object could not be retrieved" return } # Step 3: Grant NetworkService READ permission to the certificate # Check if on cloud-hosted environment if ($Script:EnvironmentType -eq [EnvironmentType]::AzureHostedTier1) { Write-PSFMessage -Level Verbose -Message "Step 3: Starting granting NetworkService READ permission to the certificate" Grant-NetworkServiceReadPermissionToCertificate -certificateObject $certificateObject if (Test-PSFFunctionInterrupt) { return } } # Step 4: Update web.config with application ID and certificate thumbprint Write-PSFMessage -Level Verbose -Message "Step 4: Starting updating web.config with application ID and certificate thumbprint" $params = @{ AOSPath = $Script:AOSPath WebConfig = $Script:WebConfig ClientId = $ClientId CertificateThumbprint = $certificateThumbprint Force = $Force } Update-WebConfig @params if (Test-PSFFunctionInterrupt) { return } # Step 5: Add app registration to Wif.config Write-PSFMessage -Level Verbose -Message "Step 5: Starting adding app registration to Wif.config" Update-WifConfig -AOSPath $Script:AOSPath -WifConfig $Script:WifConfig -ClientId $ClientId -Force:$Force if (Test-PSFFunctionInterrupt) { return } # Step 6: Clear cached LCS configuration in AxDB Write-PSFMessage -Level Verbose -Message "Step 6: Starting clearing cached LCS configuration in AxDB" Invoke-D365SqlScript -Command "DELETE FROM SYSOAUTHCONFIGURATION where SECURERESOURCE = 'https://lcsapi.lcs.dynamics.com'" Invoke-D365SqlScript -Command "DELETE FROM SYSOAUTHUSERTOKENS where SECURERESOURCE = 'https://lcsapi.lcs.dynamics.com'" Write-PSFMessage -Level Host -Message "Cached LCS configuration in AxDB was cleared." # Step 7: Restart IIS Write-PSFMessage -Level Verbose -Message "Step 7: Starting restarting IIS" Restart-D365Environment -Aos Write-PSFMessage -Level Host -Message "IIS was restarted." Test-D365EntraIntegration if ($PSCmdlet.ParameterSetName -eq "NewCertificate") { Write-PSFMessage -Level Host -Message "The certificate file $NewCertificateFile must be uploaded to the Azure application, see https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app#add-a-certificate." } } function CheckAndInstallExistingCertificate { [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory)] [string] $CertificateFile, [string] $PrivateKeyFile, [Security.SecureString] $CertificatePassword, [switch] $Force ) if (-not (Test-PathExists -Path $CertificateFile -Type Leaf)) { Write-PSFMessage -Level Host -Message "The provided certificate file $CertificateFile does not exist." Stop-PSFFunction -StepsUpward 1 -Message "Stopping because the provided certificate file does not exist" return } if ($CertificatePassword -and -not (Test-PathExists -Path $PrivateKeyFile -Type Leaf)) { Write-PSFMessage -Level Host -Message "The provided certificate private key file $PrivateKeyFile does not exist." Stop-PSFFunction -StepsUpward 1 -Message "Stopping because the provided certificate private key file does not exist" return } $certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($CertificateFile) # Check for existing certificate that has the same thumbprint as the provided certificate $existingCertificate = Get-ChildItem -Path $certificateStoreLocation -ErrorAction SilentlyContinue | Where-Object {$_.Thumbprint -eq $certificate.Thumbprint} if ($existingCertificate) { Write-PSFMessage -Level Warning -Message "A certificate with the same thumbprint as the provided certificate $CertificateFile already exists in $certificateStoreLocation." if (-not $Force) { Stop-PSFFunction -StepsUpward 1 -Message "Stopping because a certificate with the same thumbprint as the provided certificate already exists" return } Write-PSFMessage -Level Host -Message "Deleting and installing the provided certificate." $existingCertificate | Remove-Item } # Install certificate if ($CertificatePassword) { $null = Import-PfxCertificate -FilePath $PrivateKeyFile -CertStoreLocation $certificateStoreLocation -Password $CertificatePassword } $certificate = Import-Certificate -FilePath $CertificateFile -CertStoreLocation $certificateStoreLocation Write-PSFMessage -Level Host -Message "Certificate $CertificateFile installed to $certificateStoreLocation." $certificate.Thumbprint } function CreateAndInstallNewCertificate { [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory)] [string] $CertificateName, [Parameter(Mandatory)] [int] $CertificateExpirationYears, [Parameter(Mandatory)] [string] $NewCertificateFile, [string] $NewCertificatePrivateKeyFile, [Security.SecureString] $CertificatePassword, [switch] $Force ) # Check for existing certificate $existingCertificate = Get-ChildItem -Path $certificateStoreLocation -ErrorAction SilentlyContinue | Where-Object {$_.Subject -Match "$CertificateName"} if ($existingCertificate) { Write-PSFMessage -Level Warning -Message "A certificate with name $CertificateName already exists in $certificateStoreLocation with expiration date $($existingCertificate.NotAfter)." if (-not $Force) { Stop-PSFFunction -StepsUpward 1 -Message "Stopping because a certificate with the same name already exists" return } Write-PSFMessage -Level Host -Message "Deleting and re-creating the certificate." $existingCertificate | Remove-Item } # Check for existing certificate file if (Test-PathExists -Path $NewCertificateFile -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) { Write-PSFMessage -Level Warning -Message "A certificate file with the same name as the new certificate file $NewCertificateFile already exists." if (-not $Force) { Stop-PSFFunction -StepsUpward 1 -Message "Stopping because a certificate file with the same name already exists" return } Write-PSFMessage -Level Host -Message "The existing certificate file will be overwritten." } if ($CertificatePassword -and (Test-PathExists -Path $NewCertificatePrivateKeyFile -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue)) { Write-PSFMessage -Level Warning -Message "A certificate private key file with the same name as the new certificate private key file $NewCertificatePrivateKeyFile already exists." if (-not $Force) { Stop-PSFFunction -StepsUpward 1 -Message "Stopping because a certificate private key file with the same name already exists" return } Write-PSFMessage -Level Host -Message "The existing certificate private key file will be overwritten." } # Create certificate $certificateParams = @{ Subject = "CN=$CertificateName" CertStoreLocation = $certificateStoreLocation KeyExportPolicy = 'Exportable' KeySpec = 'Signature' KeyLength = 2048 KeyAlgorithm = 'RSA' HashAlgorithm = 'SHA256' NotAfter = (Get-Date).AddYears($CertificateExpirationYears) } $certificate = New-SelfSignedCertificate @certificateParams $null = Export-Certificate -Cert $certificate -FilePath $NewCertificateFile -Force:$Force Write-PSFMessage -Level Host -Message "Certificate $CertificateName created and saved to $NewCertificateFile." if ($CertificatePassword) { $null = Export-PfxCertificate -Cert $certificate -FilePath $NewCertificatePrivateKeyFile -Password $CertificatePassword -Force:$Force Write-PSFMessage -Level Host -Message "Certificate private key file $NewCertificatePrivateKeyFile created." } $certificate.Thumbprint } function Grant-NetworkServiceReadPermissionToCertificate { [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory)] [System.Security.Cryptography.X509Certificates.X509Certificate2] $certificateObject ) # Get private key container name $privateKey = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($certificateObject) $containerName = "" if ($privateKey.GetType().Name -ieq "RSACng") { $containerName = $privateKey.Key.UniqueName } else { $containerName = $privateKey.CspKeyContainerInfo.UniqueKeyContainerName } $keyFullPath = $env:ProgramData + "\Microsoft\Crypto\RSA\MachineKeys\" + $containerName if (-not (Test-PathExists -Path $keyFullPath -Type Leaf)) { Write-PSFMessage -Level Host -Message "Unable to get the private key container to set read permission for NetworkService." Stop-PSFFunction -StepsUpward 1 -Message "Stopping because the private key container to set read permission for NetworkService could not be retrieved" return } # Grant NetworkService account access to certificate if it does not already have it $networkServiceSidType = [System.Security.Principal.WellKnownSidType]::NetworkServiceSid $readFileSystemRight = [System.Security.AccessControl.FileSystemRights]::Read $allowAccessControlType = [System.Security.AccessControl.AccessControlType]::Allow $networkServiceSID = New-Object System.Security.Principal.SecurityIdentifier($networkServiceSidType, $null) $permissions = (Get-Item $keyFullPath).GetAccessControl() $newRuleSet = 0 $identityNetwork = $permissions.access ` | Where-Object {$_.identityreference -eq "$($networkServiceSID.Translate([System.Security.Principal.NTAccount]).value)"} ` | Select-Object if ($identityNetwork.IdentityReference -ne "$($networkServiceSID.Translate([System.Security.Principal.NTAccount]).value)") { $rule1 = New-Object Security.AccessControl.FileSystemAccessRule($networkServiceSID, $readFileSystemRight, $allowAccessControlType) $permissions.AddAccessRule($rule1) $newRuleSet = 1 Write-PSFMessage -Level Verbose -Message "Added NetworkService with READ access to certificate" } elseif ($identityNetwork.FileSystemRights -ne $readFileSystemRight) { $rule1 = New-Object Security.AccessControl.FileSystemAccessRule($networkServiceSID, $readFileSystemRight, $allowAccessControlType) $permissions.AddAccessRule($rule1) $newRuleSet = 1 Write-PSFMessage -Level Verbose -Message "Gave NetworkService READ access to certificate" } if ($newRuleSet -eq 1){ Set-Acl -Path $keyFullPath -AclObject $permissions Write-PSFMessage -Level Host -Message "NetworkService was granted READ permission to the certificate." } } function Update-WebConfig { [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory)] [string] $AOSPath, [Parameter(Mandatory)] [string] $WebConfig, [Parameter(Mandatory)] [string] $ClientId, [Parameter(Mandatory)] [string] $CertificateThumbprint, [switch] $Force ) Write-PSFMessage -Level Verbose -Message "Starting updating web.config" $webConfigBackup = Join-Path $Script:DefaultTempPath "WebConfigBackup" $webConfigFileBackup = Join-Path $webConfigBackup $WebConfig if (Test-PathExists -Path $webConfigFileBackup -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) { Write-PSFMessage -Level Warning -Message "Backup of web.config already exists." if (-not $Force) { Stop-PSFFunction -StepsUpward 1 -Message "Stopping because a backup of web.config already exists" return } Write-PSFMessage -Level Host -Message "Backup of web.config will be overwritten." } $null = Backup-D365WebConfig -Force:$Force $webConfigFile = Join-Path -Path $AOSPath $WebConfig if (-not (Test-PathExists -Path $webConfigFile -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue)) { Write-PSFMessage -Level Host -Message "Unable to find the web.config file." Stop-PSFFunction -StepsUpward 1 -Message "Stopping because the web.config file could not be found" return } [xml]$xml = Get-Content $webConfigFile $nodes = ($xml.configuration.appSettings).ChildNodes $aadRealm = $nodes | Where-Object -Property Key -eq "Aad.Realm" $aadRealm.value = "spn:$ClientId" $infraThumb = $nodes | Where-Object -Property Key -eq "Infrastructure.S2SCertThumbprint" $infraThumb.value = $CertificateThumbprint $graphThumb = $nodes | Where-Object -Property Key -eq "GraphApi.GraphAPIServicePrincipalCert" $graphThumb.value = $CertificateThumbprint if ($PSCmdlet.ShouldProcess($WebConfig, "Update")) { $xml.Save($webConfigFile) Write-PSFMessage -Level Host -Message "web.config was updated with the application ID and the thumbprint of the certificate." } } function Update-WifConfig { [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory)] [string] $AOSPath, [Parameter(Mandatory)] [string] $WifConfig, [Parameter(Mandatory)] [string] $ClientId, [switch] $Force ) Write-PSFMessage -Level Verbose -Message "Step 5: Starting adding app registration to Wif.config" $wifConfigBackup = Join-Path $Script:DefaultTempPath "WifConfigBackup" $wifConfigFileBackup = Join-Path $wifConfigBackup $WifConfig if (Test-PathExists -Path $wifConfigFileBackup -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) { Write-PSFMessage -Level Warning -Message "Backup of Wif.config already exists." if (-not $Force) { Stop-PSFFunction -StepsUpward 1 -Message "Stopping because a backup of Wif.config already exists" return } Write-PSFMessage -Level Host -Message "Backup of Wif.config will be overwritten." } $null = Backup-D365WifConfig -Force:$Force $wifConfigFile = Join-Path -Path $AOSPath $WifConfig if (-not (Test-PathExists -Path $wifConfigFile -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue)) { Write-PSFMessage -Level Host -Message "Unable to find the Wif.config file." Stop-PSFFunction -StepsUpward 1 -Message "Stopping because the Wif.config file could not be found" return } [xml]$xml = Get-Content $wifConfigFile $audienceUris = $xml.'system.identityModel'.identityConfiguration.securityTokenHandlers.securityTokenHandlerConfiguration.audienceUris $existingAudienceUri = $audienceUris.ChildNodes | Where-Object {$_.value -eq "spn:$ClientId"} if (-not $existingAudienceUri) { $audienceUriElement = $xml.CreateElement('add') $audienceUriElement.SetAttribute('value', "spn:$ClientId") $audienceUris.AppendChild($audienceUriElement) if ($PSCmdlet.ShouldProcess($WifConfig, "Update")) { $xml.Save($wifConfigFile) Write-PSFMessage -Level Host -Message "Wif.config was updated with the audience URI." } } else { Write-PSFMessage -Level Host -Message "Audience URI already exists in Wif.config." } } ================================================ FILE: d365fo.tools/functions/new-d365isvlicense.ps1 ================================================  <# .SYNOPSIS Create a license deployable package .DESCRIPTION Create a deployable package with a license file inside .PARAMETER LicenseFile Path to the license file that you want to have inside a deployable package .PARAMETER Path Path to the template zip file for creating a deployable package with a license file Default path is the same as the aos service "PackagesLocalDirectory\bin\CustomDeployablePackage\ImportISVLicense.zip" .PARAMETER OutputPath Path where you want the generated deployable package stored Default value is: "C:\temp\d365fo.tools\ISVLicense.zip" .EXAMPLE PS C:\> New-D365ISVLicense -LicenseFile "C:\temp\ISVLicenseFile.txt" This will take the "C:\temp\ISVLicenseFile.txt" file and locate the "ImportISVLicense.zip" template file under the "PackagesLocalDirectory\bin\CustomDeployablePackage\". It will extract the "ImportISVLicense.zip", load the ISVLicenseFile.txt and compress (zip) the files into a deployable package. The package will be exported to "C:\temp\d365fo.tools\ISVLicense.zip" .NOTES Author: Mötz Jensen (@splaxi) Author: Szabolcs Eötvös Author: Florian Hopfner (@FH-Inway) #> function New-D365ISVLicense { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string] $LicenseFile, [Alias('Template')] [string] $Path = "$Script:BinDirTools\CustomDeployablePackage\ImportISVLicense.zip", [string] $OutputPath = "C:\temp\d365fo.tools\ISVLicense.zip" ) begin { $oldprogressPreference = $global:progressPreference $global:progressPreference = 'silentlyContinue' } process { Add-FileToPackage -File $LicenseFile -Archive $Path -Path "AosService\Scripts\License" -OutputPath $OutputPath -ClearPath } end { $global:progressPreference = $oldprogressPreference } } ================================================ FILE: d365fo.tools/functions/new-d365moduletoremove.ps1 ================================================  <# .SYNOPSIS Create a new ModuleToRemove.txt file .DESCRIPTION Create a new ModuleToRemove.txt file based on a list of module names .PARAMETER Path Path to the ModuleToRemove.txt file .PARAMETER Modules The array with all the module names that you want to fill into the ModuleToRemove.txt file .EXAMPLE PS C:\> New-D365ModuleToRemove -Path C:\Temp -Modules "MyRemovedModule1","MySecondRemovedModule" This will create a new ModuleToRemove.txt file and fill in "MyRemovedModule1" and "MySecondRemovedModule" as the modules to remove. The new file is stored at "C:\Temp\ModuleToRemove.txt" .EXAMPLE PS C:\> New-D365ModuleToRemove -Path C:\Temp -Modules "MyRemovedModule1","MySecondRemovedModule" | Add-D365ModuleToRemove -DeployablePackage C:\Temp\DeployablePackage.zip 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. .LINK Add-D365ModuleToRemove .NOTES Author: Florian Hopfner (@FH-Inway) #> function New-D365ModuleToRemove { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 1 )] [alias('Folder')] [string] $Path, [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 2 )] [string[]] $Modules ) begin { } process { if (Test-PathExists -Path $Path -Type Container) { Remove-Item -Path $Path\ModuleToRemove.txt -Force -ErrorAction SilentlyContinue $Modules | ForEach-Object { Add-Content -Path $Path\ModuleToRemove.txt -Value $_ } Write-PSFMessage -Level Host -Message "ModuleToRemove.txt created at $Path" -Target $Path [PSCustomObject]@{ ModuleToRemove = "$Path\ModuleToRemove.txt" } } else { Write-PSFMessage -Level Warning -Message "The path $Path does not exist" -Target $Path } } end { } } ================================================ FILE: d365fo.tools/functions/new-d365topologyfile.ps1 ================================================  <# .SYNOPSIS Create a new topology file .DESCRIPTION Build a new topology file based on a template and update the ServiceModelList .PARAMETER Path Path to the template topology file .PARAMETER Services The array with all the service names that you want to fill into the topology file .PARAMETER NewPath Path to where you want to save the new file after it has been created .EXAMPLE PS C:\> New-D365TopologyFile -Path C:\Temp\DefaultTopologyData.xml -Services "ALMService","AOSService","BIService" -NewPath C:\temp\CurrentTopology.xml This will read the "DefaultTopologyData.xml" file and fill in "ALMService","AOSService" and "BIService" as the services in the ServiceModelList tag. The new file is stored at "C:\temp\CurrentTopology.xml" .EXAMPLE PS C:\> $Services = @(Get-D365InstalledService | ForEach-Object {$_.Servicename}) PS C:\> New-D365TopologyFile -Path C:\Temp\DefaultTopologyData.xml -Services $Services -NewPath C:\temp\CurrentTopology.xml This will get all the services already installed on the machine. Afterwards the list is piped to New-D365TopologyFile where all services are import into the new topology file that is stored at "C:\temp\CurrentTopology.xml" .NOTES Author: Mötz Jensen (@Splaxi) #> function New-D365TopologyFile { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 1 )] [alias('File')] [string] $Path, [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 2 )] [string[]] $Services, [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 3 )] [alias('NewFile')] [string] $NewPath ) begin { } process { if (Test-PathExists -Path $Path -Type Leaf) { Remove-Item -Path $NewPath -Force -ErrorAction SilentlyContinue [xml]$topology = [xml](Get-Content -Path $Path) [System.Collections.ArrayList] $ServicesList = New-Object -TypeName "System.Collections.ArrayList" foreach ($obj in $Services) { $null = $ServicesList.Add("$obj") } $topology.TopologyData.MachineList.Machine.ServiceModelList.InnerXml = (($ServicesList.ToArray()) -join [Environment]::NewLine ) $sw = New-Object System.Io.Stringwriter $writer = New-Object System.Xml.XmlTextWriter($sw) $writer.Formatting = [System.Xml.Formatting]::Indented $writer.Indentation = 4; $topology.WriteContentTo($writer) $topology.LoadXml($sw.ToString()) $topology.Save("$NewPath") } else { 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." Stop-PSFFunction -Message "Stopping because of errors" return } } end { } } ================================================ FILE: d365fo.tools/functions/publish-d365ssrsreport.ps1 ================================================  <# .SYNOPSIS Deploy Report .DESCRIPTION Deploy SSRS Report to SQL Server Reporting Services .PARAMETER Module Name of the module that you want to works against Accepts an array of strings Default value is "*" and will work against all modules loaded on the machine .PARAMETER ReportName Name of the report that you want to deploy Default value is "*" and will deploy all reports from the module(s) that you speficied .PARAMETER LogFile Path to the file that should contain the logging information Default value is "c:\temp\d365fo.tools\AxReportDeployment.log" .PARAMETER PackageDirectory Path to the PackagesLocalDirectory Default path is the same as the AOS Service PackagesLocalDirectory .PARAMETER ToolsBasePath Base path to the folder containing the needed PowerShell manifests that the cmdlet utilizes Default path is the same as the AOS Service PackagesLocalDirectory .PARAMETER ReportServerIp IP Address of the server that has SQL Reporting Services installed Default value is "127.0.01" .EXAMPLE PS C:\> Publish-D365SsrsReport -Module ApplicationSuite -ReportName TaxVatRegister.Report This will deploy the report which is named "TaxVatRegister.Report". The cmdlet will look for the report inside the ApplicationSuite module. The cmdlet will be using the default 127.0.0.1 while deploying the report. .EXAMPLE PS C:\> Publish-D365SsrsReport -Module ApplicationSuite -ReportName * This will deploy the all reports from the ApplicationSuite module. The cmdlet will be using the default 127.0.0.1 while deploying the report. .NOTES Tags: SSRS, Report, Reports, Deploy, Publish Author: Mötz Jensen (@Splaxi) #> function Publish-D365SsrsReport { [CmdletBinding()] [OutputType('[PsCustomObject]')] param ( [Parameter(Mandatory = $false)] [string[]] $Module = "*", [Parameter(Mandatory = $false)] [string[]] $ReportName = "*", [Parameter(Mandatory = $false)] [string] $LogFile = (Join-Path $Script:DefaultTempPath "AxReportDeployment.log"), [Parameter(Mandatory = $false)] [string] $PackageDirectory = $Script:PackageDirectory, [Parameter(Mandatory = $false)] [string] $ToolsBasePath = $Script:PackageDirectory, [Parameter(Mandatory = $false)] [string[]]$ReportServerIp = "127.0.0.1" ) Invoke-TimeSignal -Start $LogDirectory = Split-Path $LogFile -Parent $toolsPath = Join-Path $ToolsBasePath "Plugins\AxReportVmRoleStartupTask" if (-not (Test-PathExists -Path $toolsPath, $PackageDirectory -Type Container)) { return } if (-not (Test-PathExists -Path $LogDirectory -Type Container -Create)) { return } $aosCommonManifest = Join-Path $toolsPath "AosCommon.psm1" $reportingManifest = Join-Path $toolsPath "Reporting.psm1" if (-not (Test-PathExists -Path $aosCommonManifest, $reportingManifest -Type Leaf)) { return } Write-PSFMessage -Level Verbose -Message "Importing the Microsoft AosCommon PowerShell manifest file." -Target $aosCommonManifest Import-Module "$aosCommonManifest" -Force -DisableNameChecking Write-PSFMessage -Level Verbose -Message "Importing the Microsoft Reporting PowerShell manifest file." -Target $reportingManifest Import-Module "$reportingManifest" -Force -DisableNameChecking # create JSON config string for Deploy-AxReports $settings = New-Object -TypeName PSCustomObject -Property @{ "BiReporting.ReportingServers" = $($ReportServerIp -join ",") "Microsoft.Dynamics.AX.AosConfig.AzureConfig.bindir" = $PackageDirectory "Module" = $Module "ReportName" = $ReportName } Write-PSFMessage -Level Verbose -Message "Done building the settings object that will be parsed." -Target $settings $jsonConfig = ConvertTo-Json $settings Write-PSFMessage -Level Verbose -Message "Settings object converted to json." -Target $jsonConfig $jsonConfig = [System.Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($jsonConfig)) try { Write-PSFMessage -Level Verbose -Message "Invoking the 'Deploy-AxReport' cmdlet from Microsoft." Deploy-AxReport -Config $jsonConfig -Log $LogFile } catch { Write-PSFMessage -Level Host -Message "Something went wrong while deploying the SSRS Report(s)" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } Invoke-TimeSignal -End [PSCustomObject]@{ LogFile = $LogFile } } ================================================ FILE: d365fo.tools/functions/publish-d365webresources.ps1 ================================================  <# .SYNOPSIS Deploy web resources .DESCRIPTION Deploys the Dynamics 365 for Finance and Operations web resources to the AOS service web root path. .PARAMETER PackageDirectory Path to the package directory containing the web resources. .PARAMETER AosServiceWebRootPath Path to the AOS service web root path. .EXAMPLE PS C:\> Publish-D365WebResources This will deploy the web resources to the AOS service web root path. .NOTES Author: Florian Hopfner (@FH-Inway) #> function Publish-D365WebResources { [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', 'Publish-D365WebResources')] [CmdletBinding()] param ( [Parameter(Mandatory = $false)] [PsfDirectory] $PackageDirectory = $Script:PackageDirectory, [Parameter(Mandatory = $false)] [PsfDirectory] $AosServiceWebRootPath = $Script:AOSPath ) Invoke-TimeSignal -Start Write-PSFMessage -Level Verbose -Message "Initializing web resources deplyoment." $webResourceTypes = @("Images", "Scripts", "Styles", "Html") Write-PSFMessage -Level Debug -Message "Creating web resources directory." $resourcesDirectory = Join-Path $AosServiceWebRootPath "Resources" Test-PathExists -Path $resourcesDirectory -Type Container -Create | Out-Null $params = @{ ResourceTypes = $webResourceTypes PublishingDirectory = $resourcesDirectory PackageDirectory = $PackageDirectory AosServiceWebRootPath = $AosServiceWebRootPath } Publish-D365FOResources @params Write-PSFMessage -Level Host -Message "Web resources deployment completed." Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/register-d365azurestorageconfig.ps1 ================================================  <# .SYNOPSIS Register Azure Storage Configurations .DESCRIPTION Register all Azure Storage Configurations .PARAMETER ConfigStorageLocation Parameter used to instruct where to store the configuration objects The default value is "User" and this will store all configuration for the active user Valid options are: "User" "System" "System" will store the configuration as default for all users, so they can access the configuration objects .EXAMPLE PS C:\> Register-D365AzureStorageConfig -ConfigStorageLocation "System" This will store all Azure Storage Configurations as defaults for all users on the machine. .NOTES Tags: Configuration, Azure, Storage Author: Mötz Jensen (@Splaxi) #> function Register-D365AzureStorageConfig { [CmdletBinding()] [OutputType()] param ( [ValidateSet('User', 'System')] [string] $ConfigStorageLocation = "User" ) $configScope = Test-ConfigStorageLocation -ConfigStorageLocation $ConfigStorageLocation Register-PSFConfig -FullName "d365fo.tools.azure.storage.accounts" -Scope $configScope } ================================================ FILE: d365fo.tools/functions/remove-d365broadcastmessageconfig.ps1 ================================================  <# .SYNOPSIS Remove broadcast message configuration .DESCRIPTION Remove a broadcast message configuration from the configuration store .PARAMETER Name Name of the broadcast message configuration you want to remove from the configuration store .PARAMETER Temporary Instruct the cmdlet to only temporarily remove the broadcast message configuration from the configuration store .EXAMPLE PS C:\> Remove-D365BroadcastMessageConfig -Name "UAT" This will remove the broadcast message configuration name "UAT" from the machine. .NOTES Tags: Servicing, Broadcast, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret Author: Mötz Jensen (@Splaxi) .LINK Add-D365BroadcastMessageConfig .LINK Clear-D365ActiveBroadcastMessageConfig .LINK Get-D365ActiveBroadcastMessageConfig .LINK Get-D365BroadcastMessageConfig .LINK Send-D365BroadcastMessage .LINK Set-D365ActiveBroadcastMessageConfig #> function Remove-D365BroadcastMessageConfig { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] [OutputType()] param ( [Parameter(Mandatory = $true, Position = 1)] [string] $Name, [switch] $Temporary ) $Name = $Name.ToLower() if ($Name -match '\*') { Write-PSFMessage -Level Host -Message "The name cannot contain wildcard character." Stop-PSFFunction -Message "Stopping because the name contains wildcard character." return } if (-not ((Get-PSFConfig -FullName "d365fo.tools.broadcast.*.name").Value -contains $Name)) { Write-PSFMessage -Level Host -Message "A broadcast message configuration with that name doesn't exists." Stop-PSFFunction -Message "Stopping because a broadcast message configuration with that name doesn't exists." return } $res = (Get-PSFConfig -FullName "d365fo.tools.active.broadcast.message.config.name").Value if ($res -eq $Name) { Write-PSFMessage -Level Host -Message "The active broadcast message configuration is the same as the one you're trying to remove. Please set another configuration as active, before removing this one. You could also call Clear-D365ActiveBroadcastMessageConfig." Stop-PSFFunction -Message "Stopping because the active broadcast message configuration is the same as the one trying to be removed." return } foreach ($config in Get-PSFConfig -FullName "d365fo.tools.broadcast.$Name.*") { Set-PSFConfig -FullName $config.FullName -Value "" if (-not $Temporary) { Unregister-PSFConfig -FullName $config.FullName -Scope UserDefault } } } ================================================ FILE: d365fo.tools/functions/remove-d365database.ps1 ================================================  <# .SYNOPSIS Removes a database .DESCRIPTION Removes a database. By default, if no other database is specified, the AxDB database will be removed. .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .PARAMETER Confirm This parameter will prompt you for confirmation before executing steps of the command that have a medium impact. .PARAMETER WhatIf This parameter will simulate the actions of the command. No changes will be made. .PARAMETER Force This parameter will suppress the confirmation prompt. It can be used as an alternative to -Confirm:$false .EXAMPLE PS C:\> Remove-D365Database This will remove the "AxDB" database from the default SQL Server instance that is registered on the machine. .EXAMPLE PS C:\> Remove-D365Database -DatabaseName "ExportClone" This will remove the "ExportClone" from the default SQL Server instance that is registered on the machine. .NOTES Author: Mötz Jensen (@Splaxi) Author: Florian Hopfner (@FH-Inway) #> function Remove-D365Database { [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] param ( [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword, [switch] $EnableException, [switch] $Force ) if ($Force -and -not $PSBoundParameters.ContainsKey('Confirm')) { $ConfirmPreference = 'None' } $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $null = [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO') $srv = new-object Microsoft.SqlServer.Management.Smo.Server("$DatabaseServer") if (-not $UseTrustedConnection) { $srv.ConnectionContext.set_LoginSecure($false) $srv.ConnectionContext.set_Login("$SqlUser") $srv.ConnectionContext.set_Password("$SqlPwd") } try { $db = $srv.Databases["$DatabaseName"] if (!$db) { Write-PSFMessage -Level Warning -Message "Database $DatabaseName not found. Nothing to remove." return } if ($srv.ServerType -ne "SqlAzureDatabase") { if ($PSCmdlet.ShouldProcess("$DatabaseName", "Kill all processes")) { $srv.KillAllProcesses("$DatabaseName") } } Write-PSFMessage -Level Verbose -Message "Dropping $DatabaseName" -Target $DatabaseName if ($PSCmdlet.ShouldProcess("$DatabaseName", "Drop database")) { $db.Drop() Write-PSFMessage -Level Output -Message "Database $DatabaseName was removed." } } catch { $messageString = "Something went wrong while removing the Database." Write-PSFMessage -Level Host -Message $messageString Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -StepsUpward 1 return } } ================================================ FILE: d365fo.tools/functions/remove-d365lcsassetfile.ps1 ================================================  <# .SYNOPSIS Delete asset from the LCS project Asset Library .DESCRIPTION Delete asset from the LCS project Asset Library .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig .PARAMETER AssetId LCS Id of the file that you are looking for .PARAMETER BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Remove-D365LcsAssetFile -ProjectId 123456789 -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" -AssetId "812bcb0e-23fb-476d-8a92-985f20a704b9" This will delete the Asset file from the LCS Asset Library. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .LINK Get-D365LcsApiConfig .LINK Get-D365LcsApiToken .LINK Invoke-D365LcsApiRefreshToken .LINK Set-D365LcsApiConfig .LINK Remove-LcsAssetFile .NOTES Author: Oleksandr Nikolaiev (@onikolaiev) #> function Remove-D365LcsAssetFile { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] [OutputType()] param ( [int] $ProjectId = $Script:LcsApiProjectId, [Parameter(Mandatory = $true)] [string] $AssetId = "", [Alias('Token')] [string] $BearerToken = $Script:LcsApiBearerToken, [string] $LcsApiUri = $Script:LcsApiLcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) Invoke-TimeSignal -Start if (-not ($BearerToken.StartsWith("Bearer "))) { $BearerToken = "Bearer $BearerToken" } Remove-LcsAssetFile -BearerToken $BearerToken -ProjectId $ProjectId -LcsApiUri $LcsApiUri -RetryTimeout $RetryTimeout -AssetId $AssetId if (Test-PSFFunctionInterrupt) { return } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/remove-d365model.ps1 ================================================  <# .SYNOPSIS Remove a model from Dynamics 365 for Finance & Operations .DESCRIPTION Remove a model from a Dynamics 365 for Finance & Operations environment .PARAMETER Model Name of the model that you want to work against .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin Default value is fetched from the current configuration on the machine .PARAMETER MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory .PARAMETER DeleteFolders Instruct the cmdlet to delete the model folder This is useful when you are trying to clean up the folders in your source control / branch .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .EXAMPLE PS C:\> Remove-D365Model -Model CustomModelName This will remove the "CustomModelName" model from the D365FO environment. It will NOT remove the folders inside the PackagesLocalDirectory location. .EXAMPLE PS C:\> Remove-D365Model -Model CustomModelName -DeleteFolders This will remove the "CustomModelName" model from the D365FO environment. It will remove the folders inside the PackagesLocalDirectory location. This is helpful when dealing with source control and you want to remove the model entirely. .NOTES Tags: ModelUtil, Axmodel, Model, Remove, Delete, Source Control, Vsts, Azure DevOps Author: Mötz Jensen (@Splaxi) #> function Remove-D365Model { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $Model, [Parameter(Mandatory = $false)] [string] $BinDir = "$Script:PackageDirectory\bin", [Parameter(Mandatory = $false)] [string] $MetaDataDir = "$Script:MetaDataDir", [switch] $DeleteFolders, [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) Invoke-TimeSignal -Start Invoke-ModelUtil -Command "Delete" -Path $Path -BinDir $BinDir -MetaDataDir $MetaDataDir -Model $Model -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly if (Test-PSFFunctionInterrupt) { return } $modelPath = Join-Path $MetaDataDir $Model if ($DeleteFolders) { if (-not (Test-PathExists -Path $modelPath -Type Container)) { return } Remove-Item $modelPath -Force -Recurse -ErrorAction SilentlyContinue } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/functions/remove-d365user.ps1 ================================================  <# .SYNOPSIS Delete an user from the environment .DESCRIPTION Deletes the user from the database, including security configuration .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER Email The search string to select which user(s) should be updated. You have to specific the explicit email address of the user you want to remove The cmdlet will not be able to delete the ADMIN user, this is to prevent you from being locked out of the system. .EXAMPLE PS C:\> Remove-D365User -Email "Claire@contoso.com" This will move all security and user details from the user with the email address "Claire@contoso.com" .EXAMPLE PS C:\> Get-D365User -Email *contoso.com | Remove-D365User This will first get all users from the database that matches the *contoso.com search and pipe their emails to Remove-D365User for it to delete them. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Remove-D365User { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 1)] [string] $DatabaseServer = $Script:DatabaseServer, [Parameter(Mandatory = $false, Position = 2)] [string] $DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, Position = 3)] [string] $SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, Position = 4)] [string] $SqlPwd = $Script:DatabaseUserPassword, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 5)] [string] $Email ) BEGIN { $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection try { $SqlCommand.Connection.Open() } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } PROCESS { if(Test-PSFFunctionInterrupt) {return} $SqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\remove-user.sql") -join [Environment]::NewLine $null = $SqlCommand.Parameters.AddWithValue("@Email", $Email) try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $null = $SqlCommand.ExecuteNonQuery() } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } $SqlCommand.Parameters.Clear() } END { try { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } } ================================================ FILE: d365fo.tools/functions/rename-d365computername.ps1 ================================================  <# .SYNOPSIS Function for renaming computer. Renames Computer and changes the SSRS Configration .DESCRIPTION When doing development on-prem, there is as need for changing the Computername. Function both changes Computername and SSRS Configuration .PARAMETER NewName The new name for the computer .PARAMETER SSRSReportDatabase Name of the SSRS reporting database .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Rename-D365ComputerName -NewName "Demo-8.1" -SSRSReportDatabase "ReportServer" This will rename the local machine to the "Demo-8.1" as the new Windows machine name. It will update the registration inside the SQL Server Reporting Services configuration to handle the new name of the machine. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Rename-D365ComputerName { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $NewName, [string] $SSRSReportDatabase = "DynamicsAxReportServer", [string] $DatabaseServer = $Script:DatabaseServer, [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword, [Alias('LogDir')] [string] $LogPath = $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\RsConfig"), [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly, [switch] $EnableException ) Write-PSFMessage -Level Verbose -Message "Testing for elevated runtime" if (!$script:IsAdminRuntime) { Write-PSFMessage -Level Host -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." Stop-PSFFunction -Message "Stopping because the function is not run elevated" return } $executable = "$Script:SSRSTools\rsconfig.exe" $SSRSInstance = "SSRS" if (-not (Test-PathExists -Path $executable -Type Leaf)) { $executable = "$Script:SQLTools\rsconfig.exe" # fall back to pre 10.0.24 $SSRSInstance = "" # no instance name needed for old VMs if (-not (Test-PathExists -Path $executable -Type Leaf)) { return } } if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "Renaming computer to $NewName" Rename-Computer -NewName $NewName -Force Write-PSFMessage -Level Verbose -Message "Renaming local server name inside SQL Server to $NewName" $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $Params = @{DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd; TrustedConnection = $UseTrustedConnection; } $oldComputerName = $env:COMPUTERNAME $sqlCommand = Get-SQLCommand @Params $commandText = (Get-Content "$script:ModuleRoot\internal\sql\rename-computer.sql") -join [Environment]::NewLine $commandText = $commandText.Replace('@OldComputerName', $oldComputerName) $commandText = $commandText.Replace('@NewComputerName', $NewName) $sqlCommand.CommandText = $commandText try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $null = $sqlCommand.ExecuteNonQuery() } catch { $messageString = "Something went wrong while working against the database." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } $sqlCommand = Get-SQLCommand @Params Write-PSFMessage -Level Verbose -Message "Setting SSRS Reporting server database server to localhost" $params = New-Object System.Collections.Generic.List[string] $params.Add("-s") $params.Add("localhost") $params.Add("-a") $params.Add("Windows") $params.Add("-c") $params.Add("-d") $params.Add("`"$SSRSReportDatabase`"") if ($SSRSInstance) { $params.Add("-i") $params.Add("`"$SSRSInstance`"") } Invoke-Process -Executable $executable -Params $params.ToArray() -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath if (-not $OutputCommandOnly) { Write-PSFMessage -Level Host -Message "Computer has been renamed. Please restart the computer to make sure that all changes are being applied correctly." } } ================================================ FILE: d365fo.tools/functions/rename-d365instance.ps1 ================================================  <# .SYNOPSIS Rename as D365FO Demo/Dev box .DESCRIPTION The Rename function, changes the config values used by a D365FO dev box for identifying its name. Standard it is called 'usnconeboxax1aos' .PARAMETER NewName The new name wanted for the D365FO instance .PARAMETER AosServiceWebRootPath Path to the webroot folder for the AOS service 'Default value : C:\AOSService\Webroot .PARAMETER IISServerApplicationHostConfigFile Path to the IISService Application host file, [Where the binding configurations is stored] 'Default value : C:\Windows\System32\inetsrv\Config\applicationHost.config' .PARAMETER HostsFile Place of the host file on the current system [Local DNS record] ' Default value C:\Windows\System32\drivers\etc\hosts' .PARAMETER BackupExtension Backup name for all the files that are changed .PARAMETER MRConfigFile Path to the Financial Reporter (Management Reporter) configuration file .EXAMPLE PS C:\> Rename-D365Instance -NewName "Demo1" This will rename the D365 for Finance & Operations instance to "Demo1". This IIS will be restarted while doing it. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) The function restarts the IIS Service. Elevated privileges are required. #> function Rename-D365Instance { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string]$NewName, [string]$AosServiceWebRootPath = $Script:AOSPath, [string]$IISServerApplicationHostConfigFile = $Script:IISHostFile, [string]$HostsFile = $Script:Hosts, [string]$BackupExtension = "bak", [string]$MRConfigFile = $Script:MRConfigFile ) Write-PSFMessage -Level Verbose -Message "Testing for elevated runtime" if ($Script:EnvironmentType -ne [EnvironmentType]::LocalHostedTier1) { 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 onebox / local tier 1 machine." Stop-PSFFunction -Message "Stopping because machine isn't a onebox" return } elseif (!$script:IsAdminRuntime) { Write-PSFMessage -Level Host -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." Stop-PSFFunction -Message "Stopping because the function is not run elevated" return } $OldName = (Get-D365InstanceName).Instancename Write-PSFMessage -Level Verbose -Message "Old name collected and will be used to rename." -Target $OldName # Variables $replaceValue = $OldName $NewNameDot = "$NewName." $replaceValueDot = "$replaceValue." $WebConfigFile = join-Path -path $AosServiceWebRootPath $Script:WebConfig $WifServicesFile = Join-Path -Path $AosServiceWebRootPath $Script:WifServicesConfig $Files = @($WebConfigFile, $WifServicesFile, $IISServerApplicationHostConfigFile, $HostsFile, $MRConfigFile) if(-not (Test-PathExists -Path $Files -Type Leaf)) { return } Write-PSFMessage -Level Verbose -Message "Stopping the IIS." iisreset /stop # Backup files if ($null -ne $BackupExtension -and $BackupExtension -ne '') { foreach ($item in $Files) { Backup-File -File $item -Suffix $BackupExtension } } # WebConfig - D365 web config file Rename-ConfigValue $WebConfigFile $NewName $replaceValue # Wif.Services - D365 web config file (services) Rename-ConfigValue $WifServicesFile $NewName $replaceValue #ApplicationHost - IIS Bindings Rename-ConfigValue $IISServerApplicationHostConfigFile $NewNameDot $replaceValueDot #Hosts file - local DNS cache Rename-ConfigValue $HostsFile $NewNameDot $replaceValueDot #Management Reporter Rename-ConfigValue $MRConfigFile $NewName $replaceValue #Start IIS again Write-PSFMessage -Level Verbose -Message "Starting the IIS." iisreset /start Get-D365Url -Force } ================================================ FILE: d365fo.tools/functions/repair-d365bacpacmodelfile.ps1 ================================================  <# .SYNOPSIS Repair a bacpac model file .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 .PARAMETER Path Path to the bacpac model file that you want to work against .PARAMETER OutputPath Path to where the repaired model file should be placed The default value is going to create a file next to the Path (input) file, with the '-edited' name appended to it .PARAMETER PathRepairSimple Path to the json file, that contains all the instructions to be executed in the "Simple" section The default json file is part of the module, and can be located with the below command: explorer.exe $(Join-Path -Path $(Split-Path -Path (Get-Module d365fo.tools -ListAvailable)[0].Path -Parent) -ChildPath "internal\misc") - Look for the "RepairBacpac.Simple.json" file 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 Simple means, that we can remove complex elements, based on some basic logic. E.g. { "Search": "**" } "**" - we know when to stop. .PARAMETER PathRepairQualifier Path to the json file, that contains all the instructions to be executed in the "Qualifier" section The default json file is part of the module, and can be located with the below command: explorer.exe $(Join-Path -Path $(Split-Path -Path (Get-Module d365fo.tools -ListAvailable)[0].Path -Parent) -ChildPath "internal\misc") - Look for the "RepairBacpac.Qualifier.json" file 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 Qualifier means, that we can remove complex elements, based on some basic logic. E.g. { "Search": "**", "Qualifier": "**" } "**" can identify below, "**" - we know when to stop. .PARAMETER PathRepairReplace Path to the json file, that contains all the instructions to be executed in the "Replace" section The default json file is part of the module, and can be located with the below command: explorer.exe $(Join-Path -Path $(Split-Path -Path (Get-Module d365fo.tools -ListAvailable)[0].Path -Parent) -ChildPath "internal\misc") - Look for the "RepairBacpac.Replace.json" file 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 Replace means, that we can replace/remove strings, based on some basic logic. E.g. { "Search": "", "Replace": "" } "" can identify below, and "" is the value we want to replace with it. .PARAMETER KeepFiles Instruct the cmdlet to keep the files from the repair process 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 Use it while you evolve/develop your instructions, but remove it from ANY full automation scripts .PARAMETER Force Instruct the cmdlet to overwrite the file specified in the OutputPath if it already exists .EXAMPLE PS C:\> Repair-D365BacpacModelFile -Path C:\Temp\Base.xml -PathRepairSimple '' -PathRepairQualifier '' -PathRepairReplace 'C:\Temp\RepairBacpac.Replace.Custom.json' This will only process the Replace section, as the other repair paths are empty - indicating to skip them. It will load the instructions from the 'C:\Temp\RepairBacpac.Replace.Custom.json' file and run those in the Replace section. .EXAMPLE PS C:\> Repair-D365BacpacModelFile -Path C:\Temp\Base.xml -KeepFiles -Force This will process all repair sections. It will keep the files in the temporary work directory, for the user to analyze the files further. It will Force overwrite the output file, if it exists already. .NOTES Author: Mötz Jensen (@Splaxi) Author: Florian Hopfner (@FH-Inway) 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. This cmdlet is inspired by the work of "Brad Bateman" (github: @batetech) His github profile can be found here: https://github.com/batetech Florian Hopfner did a gist implementation, which has been used as the foundation for this implementation The original gist is: https://gist.github.com/FH-Inway/f485c720b43b72bffaca5fb6c094707e His github profile can be found here: https://github.com/FH-Inway #> function Repair-D365BacpacModelFile { [CmdletBinding()] param ( [Parameter(Mandatory)] [string] $Path, [string] $OutputPath, [string] $PathRepairSimple = "$script:ModuleRoot\internal\misc\RepairBacpac.Simple.json", [string] $PathRepairQualifier = "$script:ModuleRoot\internal\misc\RepairBacpac.Qualifier.json", [string] $PathRepairReplace = "$script:ModuleRoot\internal\misc\RepairBacpac.Replace.json", [switch] $KeepFiles, [switch] $Force ) begin { Invoke-TimeSignal -Start if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } if ([string]::IsNullOrEmpty($OutputPath)) { $OutputPath = $Path.Replace([System.IO.Path]::GetExtension($path), "-edited$([System.IO.Path]::GetExtension($path))") } if (-not $Force) { if (-not (Test-PathExists -Path $OutputPath -Type Leaf -ShouldNotExist)) { Write-PSFMessage -Level Host -Message "The $OutputPath already exists. Consider changing the OutputPath or set the Force parameter to overwrite the file." Stop-PSFFunction -Message "Stopping because output path was already present." return } } if (Test-PSFFunctionInterrupt) { return } } end { if (Test-PSFFunctionInterrupt) { return } # Create a local working directory, in the temporary directory $directoryObj = New-Item -Path "$([System.IO.Path]::GetTempPath())$((New-Guid).Guid)" -ItemType Directory -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue if ($KeepFiles) { Write-PSFMessage -Level Host -Message "The working directory used for this repair is:`r`n$($directoryObj.FullName)`r`n - Please only use the KeepFiles when needed." } # Path to help us keep track of the file and what changes have been made - troubleshooting is easier with this one $localInput = Join-Path -Path $directoryObj.FullName -ChildPath "raw.simple&replace.input.xml" $forOutput = Join-Path -Path $directoryObj.FullName -ChildPath "0.simple&replace.output.xml" # Clone input file to the local temporary file Copy-Item -Path $Path -Destination $localInput -Force $arrSimple = @() if (-not [string]::IsNullOrEmpty($PathRepairSimple)) { # Load all the simple delete instructions $arrSimple = Get-Content -Path $PathRepairSimple -Raw | ConvertFrom-Json } $arrReplace = @() if (-not [string]::IsNullOrEmpty($PathRepairReplace)) { # Load all the replace instructions $arrReplace = Get-Content -Path $PathRepairReplace -Raw | ConvertFrom-Json } Write-PSFMessage -Level Verbose -Message "Starting the Remove and Replace section of the repair." -Target @($arrSimple, $arrReplace) Repair-BacpacModelSimpleAndReplace -Path $localInput -OutputPath $forOutput -RemoveInstructions $arrSimple -ReplaceInstructions $arrReplace $arrQualifier = @() if (-not [string]::IsNullOrEmpty($PathRepairQualifier)) { # Load all the qualification delete instructions $arrQualifier = Get-Content -Path $PathRepairQualifier -Raw | ConvertFrom-Json } # Path to help us keep track of the file and what changes have been made - troubleshooting is easier with this one $localInput = Join-Path -Path $directoryObj.FullName -ChildPath "raw.qualifier.input.xml" # Clone input file to the local temporary file Copy-Item -Path $forOutput -Destination $localInput -Force if (-not $KeepFiles) { Get-ChildItem -Path "$($directoryObj.FullName)\*.simple&replace.*.xml" | Remove-Item -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue } Write-PSFMessage -Level Verbose -Message "Starting the Qualifier section of the repair." -Target @($arrSimple, $arrReplace) for ($i = 0; $i -lt $arrQualifier.Count; $i++) { $forInput = Join-Path -Path $directoryObj.FullName -ChildPath "$i.qualifier.input.xml" $forOutput = Join-Path -Path $directoryObj.FullName -ChildPath "$i.qualifier.output.xml" Copy-Item -Path $localInput -Destination $forInput -Force Repair-BacpacModelQualifier -Path $forInput -OutputPath $forOutput -Search $arrQualifier[$i].Search -Qualifier $arrQualifier[$i].Qualifier -End $arrQualifier[$i].End $localInput = $forOutput } if ($arrQualifier.Count -lt 1) { $forOutput = $localInput } Copy-Item -Path $forOutput -Destination $OutputPath -Force if (-not $KeepFiles) { Get-ChildItem -Path "$($directoryObj.FullName)\*.qualifier.*.xml" | Remove-Item -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue } [PSCustomObject]@{ File = $OutputPath Filename = $(Split-Path -Path $OutputPath -Leaf) } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/restart-d365environment.ps1 ================================================  <# .SYNOPSIS Restart the different services .DESCRIPTION Restart the different services in a Dynamics 365 Finance & Operations environment .PARAMETER ComputerName An array of computers that you want to work against .PARAMETER All Instructs the cmdlet work against all relevant services Includes: Aos Batch Financial Reporter DMF .PARAMETER Aos Instructs the cmdlet to work against the AOS (IIS) service .PARAMETER Batch Instructs the cmdlet to work against the Batch service .PARAMETER FinancialReporter Instructs the cmdlet to work against the Financial Reporter (Management Reporter 2012) .PARAMETER DMF Instructs the cmdlet to work against the DMF service .PARAMETER Kill Instructs the cmdlet to kill the service(s) that you want to restart .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .EXAMPLE PS C:\> Restart-D365Environment -All This will stop all services and then start all services again. .EXAMPLE PS C:\> Restart-D365Environment -All -ShowOriginalProgress This will stop all services and then start all services again. The progress of Stopping the different services will be written to the console / host. The progress of Starting the different services will be written to the console / host. .EXAMPLE PS C:\> Restart-D365Environment -ComputerName "TEST-SB-AOS1","TEST-SB-AOS2","TEST-SB-BI1" -All This will work against the machines: "TEST-SB-AOS1","TEST-SB-AOS2","TEST-SB-BI1". This will stop all services and then start all services again. .EXAMPLE PS C:\> Restart-D365Environment -Aos -Batch This will stop the AOS and Batch services and then start the AOS and Batch services again. .EXAMPLE PS C:\> Restart-D365Environment -FinancialReporter -DMF This will stop the FinancialReporter and DMF services and then start the FinancialReporter and DMF services again. .EXAMPLE PS C:\> Restart-D365Environment -All -Kill This will stop all services and then start all services again. It will use the Kill parameter to make sure that the services is stopped. .NOTES Tags: Environment, Service, Services, Aos, Batch, Servicing Author: Mötz Jensen (@Splaxi) #> function Restart-D365Environment { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueSwitchParameter", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )] [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 1 )] [string[]] $ComputerName = @($env:computername), [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )] [switch] $All = $true, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 2 )] [switch] $Aos, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 3 )] [switch] $Batch, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 4 )] [switch] $FinancialReporter, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 5 )] [switch] $DMF, [switch] $Kill, [Parameter(Mandatory = $False)] [switch] $ShowOriginalProgress ) Stop-D365Environment @PSBoundParameters | Format-Table $parms = Get-DeepClone $PSBoundParameters if ($parms.ContainsKey("Kill")) { $null = $Params.Remove("Kill") } Start-D365Environment @parms | Format-Table } ================================================ FILE: d365fo.tools/functions/restore-d365devconfig.ps1 ================================================  <# .SYNOPSIS Restore the DynamicsDevConfig.xml file .DESCRIPTION Will restore the DynamicsDevConfig.xml file located in the PackagesLocalDirectory\Bin folder .PARAMETER Path Path to the folder where you the desired DynamicsDevConfig.xml file that you want restored is located Default is: "C:\Temp\d365fo.tools\DevConfigBackup" .PARAMETER Force Instructs the cmdlet to overwrite the destination file if it already exists .EXAMPLE PS C:\> Restore-D365DevConfig -Force Will restore the DynamicsDevConfig.xml file, and overwrite the current DynamicsDevConfig.xml file in the PackagesLocalDirectory\Bin folder. It will use the default path "C:\Temp\d365fo.tools\DevConfigBackup" as the source directory. It will overwrite the current DynamicsDevConfig.xml file. A result set example: Filename LastModified File -------- ------------ ---- DynamicsDevConfig.xml 6/29/2021 7:31:04 PM K:\AosService\PackagesLocalDirectory\Bin\DynamicsDevConfig.xml .NOTES Tags: Web Server, IIS, IIS Express, Development Author: Sander Holvoet (@smholvoet) #> function Restore-D365DevConfig { [CmdletBinding()] [OutputType()] param ( [string] $Path = $(Join-Path $Script:DefaultTempPath "DevConfigBackup"), [switch] $Force ) begin { if ($Path -like "*$($Script:DevConfig)") { $sourceFile = $Path } else { $sourceFile = $(Join-Path -Path $Path -ChildPath $Script:DevConfig) } } process { if (-not (Test-PathExists -Path $sourceFile -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } $destinationFile = $(Join-Path -Path (Join-Path -Path $Script:PackageDirectory -ChildPath "bin") -ChildPath $Script:DevConfig) if (-not $Force) { if ((-not (Test-PathExists -Path $destinationFile -Type Leaf -ShouldNotExist -ErrorAction SilentlyContinue -WarningAction SilentlyContinue))) { Write-PSFMessage -Level Host -Message "The $destinationFile already exists. Consider changing the destination path or set the Force parameter to overwrite the file." return } } Write-PSFMessage -Level Verbose -Message "Copying from: $sourceFile" -Target $item Copy-Item -Path $sourceFile -Destination $destinationFile -Force:$Force -PassThru | Select-PSFObject "Name as Filename", "LastWriteTime as LastModified", "Fullname as File" } } ================================================ FILE: d365fo.tools/functions/restore-d365webconfig.ps1 ================================================  <# .SYNOPSIS Restore the web.config file .DESCRIPTION Will restore the web.config file located back into the AOS / IIS folder .PARAMETER Path Path to the folder where you the desired web.config file that you want restored is located Default is: "C:\Temp\d365fo.tools\WebConfigBackup" .PARAMETER Force Instructs the cmdlet to overwrite the destination file if it already exists .EXAMPLE PS C:\> Restore-D365WebConfig -Force Will restore the web.config file, and overwrite the current web.config file in the AOS / IIS folder. It will use the default path "C:\Temp\d365fo.tools\WebConfigBackup" as the source directory. It will overwrite the current web.config file. A result set example: Filename LastModified File -------- ------------ ---- web.config 6/29/2021 7:31:04 PM K:\AosService\WebRoot\web.config .NOTES Tags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB Author: Mötz Jensen (@Splaxi) #> function Restore-D365WebConfig { [CmdletBinding()] [OutputType()] param ( [string] $Path = $(Join-Path $Script:DefaultTempPath "WebConfigBackup"), [switch] $Force ) begin { if ($Path -like "*web.config") { $sourceFile = $Path } else { $sourceFile = $(Join-Path -Path $Path -ChildPath $Script:WebConfig) } } process { if (-not (Test-PathExists -Path $sourceFile -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } $destinationFile = $(Join-Path -Path $Script:AOSPath -ChildPath $Script:WebConfig) if (-not $Force) { if ((-not (Test-PathExists -Path $destinationFile -Type Leaf -ShouldNotExist -ErrorAction SilentlyContinue -WarningAction SilentlyContinue))) { Write-PSFMessage -Level Host -Message "The $destinationFile already exists. Consider changing the destination path or set the Force parameter to overwrite the file." return } } Write-PSFMessage -Level Verbose -Message "Copying from: $sourceFile" -Target $item Copy-Item -Path $sourceFile -Destination $destinationFile -Force:$Force -PassThru | Select-PSFObject "Name as Filename", "LastWriteTime as LastModified", "Fullname as File" } } ================================================ FILE: d365fo.tools/functions/send-d365broadcastmessage.ps1 ================================================  <# .SYNOPSIS Send broadcast message to online users in D365FO .DESCRIPTION Utilize the same messaging framework available from LCS and send a broadcast message to all online users in the environment .PARAMETER Tenant Azure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to send a message to .PARAMETER URL URL / URI for the D365FO environment you want to send a message to .PARAMETER ClientId The ClientId obtained from the Azure Portal when you created a Registered Application .PARAMETER ClientSecret The ClientSecret obtained from the Azure Portal when you created a Registered Application .PARAMETER TimeZone Id of the Time Zone your environment is running in You might experience that the local VM running the D365FO is running another Time Zone than the computer you are running this cmdlet from All available .NET Time Zones can be traversed with tab for this parameter The default value is "UTC" .PARAMETER StartTime The time and date you want the message to be displayed for the users Default value is NOW 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. .PARAMETER EndingInMinutes Specify how many minutes into the future you want this message / maintenance window to last Default value is 60 minutes 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. .PARAMETER OnPremise Specify if environnement is an D365 OnPremise Default value is "Not set" (= Cloud Environnement) .EXAMPLE PS C:\> Send-D365BroadcastMessage This will send a message to all active users that are working on default D365FO environment. See the RELATED LINKS section for the supporting cmdlets needed to store a default configuration. .EXAMPLE 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" This will send a message to all active users that are working on the D365FO environment located at "https://usnconeboxax1aos.cloud.onebox.dynamics.com". It will authenticate against the Azure Active Directory with the "e674da86-7ee5-40a7-b777-1111111111111" guid. It will use the ClientId "dea8d7a9-1602-4429-b138-111111111111" and ClientSecret "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522" go get access to the environment. It will use the default value "UTC" Time Zone for converting the different time and dates. It will use the default start time which is NOW. It will use the default end time which is 60 minutes. .EXAMPLE 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" This will send a message to all active users that are working on the D365FO OnPremise environment located at "https://ax-sandbox.d365fo.local". It will authenticate against Local ADFS with the "https://adfs.local/adfs" path It will use the ClientId "dea8d7a9-1602-4429-b138-111111111111" and ClientSecret "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522" go get access to the environment. It will use the default value "UTC" Time Zone for converting the different time and dates. It will use the default start time which is NOW. It will use the default end time which is 60 minutes. .NOTES 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. For OnPremise environnement use -OnPremise flag to added "namespaces/AXSF" path to D365 URL and allow to get token from local ADFS server Tags: Servicing, Message, Users, Environment Author: Mötz Jensen (@Splaxi) .LINK Add-D365BroadcastMessageConfig .LINK Clear-D365ActiveBroadcastMessageConfig .LINK Get-D365ActiveBroadcastMessageConfig .LINK Get-D365BroadcastMessageConfig .LINK Remove-D365BroadcastMessageConfig .LINK Set-D365ActiveBroadcastMessageConfig #> function Send-D365BroadcastMessage { [CmdletBinding()] [OutputType()] param ( [Parameter(Mandatory = $false, Position = 1)] [Alias('$AADGuid')] [string] $Tenant = $Script:BroadcastTenant, [Parameter(Mandatory = $false, Position = 2)] [Alias('URI')] [string] $URL = $Script:BroadcastUrl, [Parameter(Mandatory = $false, Position = 3)] [string] $ClientId = $Script:BroadcastClientId, [Parameter(Mandatory = $false, Position = 4)] [string] $ClientSecret = $Script:BroadcastClientSecret, [Parameter(Mandatory = $false, Position = 5)] [string] $TimeZone = $Script:BroadcastTimeZone, [Parameter(Mandatory = $false, Position = 6)] [datetime] $StartTime = (Get-Date), [Parameter(Mandatory = $false, Position = 7)] [int] $EndingInMinutes = $Script:BroadcastEndingInMinutes, [Parameter(Mandatory = $false, Position = 8)] [switch] $OnPremise = $Script:BroadcastOnPremise ) $URL = $URL -replace "/$", "" $bearerParms = @{ Resource = $URL ClientId = $ClientId ClientSecret = $ClientSecret } if ($OnPremise) { $bearerParms.AuthProviderUri = "$Tenant/oauth2/token" } else { $bearerParms.AuthProviderUri = "https://login.microsoftonline.com/$Tenant/oauth2/token" } $bearer = Invoke-ClientCredentialsGrant @bearerParms | Get-BearerToken $headerParms = @{ URL = $URL BearerToken = $bearer } $headers = New-AuthorizationHeaderBearerToken @headerParms [System.UriBuilder] $messageEndpoint = $URL if ($OnPremise) { $messageEndpoint.Path = "namespaces/AXSF/api/services/SysBroadcastMessageServices/SysBroadcastMessageService/AddMessage" } else { $messageEndpoint.Path = "api/services/SysBroadcastMessageServices/SysBroadcastMessageService/AddMessage" } $endTime = $StartTime.AddMinutes($EndingInMinutes) $timeZoneFound = Get-TimeZone -InputObject $TimeZone if (Test-PSFFunctionInterrupt) { return } $startTimeConverted = [System.TimeZoneInfo]::ConvertTime($startTime, [System.TimeZoneInfo]::Local, $timeZoneFound) $endTimeConverted = [System.TimeZoneInfo]::ConvertTime($endTime, [System.TimeZoneInfo]::Local, $timeZoneFound) $body = @" { "request": { "FromDateTime": "$($startTimeConverted.ToString("s"))", "ToDateTime": "$($endTimeConverted.ToString("s"))" } } "@ try { [PSCustomObject]@{ MessageId = Invoke-RestMethod -Method Post -Uri $messageEndpoint.Uri.AbsoluteUri -Headers $headers -ContentType 'application/json' -Body $body } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while trying to send a message to the users." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors." return } } ================================================ FILE: d365fo.tools/functions/set-d365activeazurestorageconfig.ps1 ================================================  <# .SYNOPSIS Set the active Azure Storage Account configuration .DESCRIPTION Updates the current active Azure Storage Account configuration with a new one .PARAMETER Name The name the Azure Storage Account configuration you want to load into the active Azure Storage Account configuration .PARAMETER ConfigStorageLocation Parameter used to instruct where to store the configuration objects The default value is "User" and this will store all configuration for the active user Valid options are: "User" "System" "System" will store the configuration so all users can access the configuration objects .PARAMETER Temporary Instruct the cmdlet to only temporarily override the persisted settings in the configuration storage .EXAMPLE PS C:\> Set-D365ActiveAzureStorageConfig -Name "UAT-Exports" This will import the "UAT-Exports" set from the Azure Storage Account configurations. It will update the active Azure Storage Account configuration. .EXAMPLE PS C:\> Set-D365ActiveAzureStorageConfig -Name "UAT-Exports" -ConfigStorageLocation "System" This will import the "UAT-Exports" set from the Azure Storage Account configurations. It will update the active Azure Storage Account configuration. The data will be stored in the system wide configuration storage, which makes it accessible from all users. .EXAMPLE PS C:\> Set-D365ActiveAzureStorageConfig -Name "UAT-Exports" -Temporary This will import the "UAT-Exports" set from the Azure Storage Account configurations. It will update the active Azure Storage Account configuration. The update will only last for the rest of this PowerShell console session. .NOTES Author: Mötz Jensen (@Splaxi) You will have to run the Initialize-D365Config cmdlet first, before this will be capable of working. You will have to run the Add-D365AzureStorageConfig cmdlet at least once, before this will be capable of working. #> function Set-D365ActiveAzureStorageConfig { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [string] $Name, [ValidateSet('User', 'System')] [string] $ConfigStorageLocation = "User", [switch] $Temporary ) $configScope = Test-ConfigStorageLocation -ConfigStorageLocation $ConfigStorageLocation if (Test-PSFFunctionInterrupt) { return } $azureStorageConfigs = [hashtable] (Get-PSFConfigValue -FullName "d365fo.tools.azure.storage.accounts") if (-not ($azureStorageConfigs.ContainsKey($Name))) { Write-PSFMessage -Level Host -Message "An Azure Storage Account with that name doesn't exists." Stop-PSFFunction -Message "Stopping because an Azure Storage Account with that name doesn't exists." return } else { $azureDetails = $azureStorageConfigs[$Name] Set-PSFConfig -FullName "d365fo.tools.active.azure.storage.account" -Value $azureDetails if (-not $Temporary) { Register-PSFConfig -FullName "d365fo.tools.active.azure.storage.account" -Scope $configScope } Update-AzureStorageVariables } } ================================================ FILE: d365fo.tools/functions/set-d365activebroadcastmessageconfig.ps1 ================================================  <# .SYNOPSIS Set the active broadcast message configuration .DESCRIPTION Updates the current active broadcast message configuration with a new one .PARAMETER Name Name of the broadcast message configuration you want to load into the active broadcast message configuration .PARAMETER Temporary Instruct the cmdlet to only temporarily override the persisted settings in the configuration store .EXAMPLE PS C:\> Set-D365ActiveBroadcastMessageConfig -Name "UAT" This will set the broadcast message configuration named "UAT" as the active configuration. .NOTES Tags: Servicing, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret, OnPremise Author: Mötz Jensen (@Splaxi) .LINK Add-D365BroadcastMessageConfig .LINK Clear-D365ActiveBroadcastMessageConfig .LINK Get-D365ActiveBroadcastMessageConfig .LINK Get-D365BroadcastMessageConfig .LINK Remove-D365BroadcastMessageConfig .LINK Send-D365BroadcastMessage #> function Set-D365ActiveBroadcastMessageConfig { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] [OutputType()] param ( [Parameter(Mandatory = $true, Position = 1)] [string] $Name, [switch] $Temporary ) if($Name -match '\*') { Write-PSFMessage -Level Host -Message "The name cannot contain wildcard character." Stop-PSFFunction -Message "Stopping because the name contains wildcard character." return } if (-not ((Get-PSFConfig -FullName "d365fo.tools.broadcast.*.name").Value -contains $Name)) { Write-PSFMessage -Level Host -Message "A broadcast message configuration with that name doesn't exists." Stop-PSFFunction -Message "Stopping because a broadcast message configuration with that name doesn't exists." return } Set-PSFConfig -FullName "d365fo.tools.active.broadcast.message.config.name" -Value $Name if (-not $Temporary) { Register-PSFConfig -FullName "d365fo.tools.active.broadcast.message.config.name" -Scope UserDefault } Update-BroadcastVariables } ================================================ FILE: d365fo.tools/functions/set-d365admin.ps1 ================================================  <# .SYNOPSIS Powershell implementation of the AdminProvisioning tool .DESCRIPTION Cmdlet using the AdminProvisioning tool from D365FO .PARAMETER AdminSignInName Email for the Admin .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Set-D365Admin "claire@contoso.com" This will provision claire@contoso.com as administrator for the environment .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) Author: Mark Furrer (@devax_mf) #> function Set-D365Admin { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [Alias('Email')] [String]$AdminSignInName, [Parameter(Mandatory = $false, Position = 2)] [string]$DatabaseServer = $Script:DatabaseServer, [Parameter(Mandatory = $false, Position = 3)] [string]$DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, Position = 4)] [string]$SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, Position = 5)] [string]$SqlPwd = $Script:DatabaseUserPassword, [switch] $EnableException ) if (-not ($script:IsAdminRuntime)) { Write-PSFMessage -Level Host -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." Stop-PSFFunction -Message "Stopping because the function is not run elevated" return } Set-AdminUser $AdminSignInName $DatabaseServer $DatabaseName $SqlUser $SqlPwd } ================================================ FILE: d365fo.tools/functions/set-d365azcopypath.ps1 ================================================  <# .SYNOPSIS Set the path for AzCopy.exe .DESCRIPTION Update the path where the module will be looking for the AzCopy.exe executable .PARAMETER Path Path to the AzCopy.exe .EXAMPLE PS C:\> Invoke-D365InstallAzCopy -Path "C:\temp\d365fo.tools\AzCopy\AzCopy.exe" This will update the path for the AzCopy.exe in the modules configuration .NOTES Author: Mötz Jensen (@Splaxi) #> function Set-D365AzCopyPath { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] [OutputType()] param ( [Parameter(Mandatory = $true)] [string] $Path ) if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } Set-PSFConfig -FullName "d365fo.tools.path.azcopy" -Value $Path Register-PSFConfig -FullName "d365fo.tools.path.azcopy" Update-ModuleVariables } ================================================ FILE: d365fo.tools/functions/set-d365clickoncetrustprompt.ps1 ================================================  <# .SYNOPSIS Set the ClickOnce needed configuration .DESCRIPTION Creates the needed registry keys and values for ClickOnce to work on the machine .EXAMPLE PS C:\> Set-D365ClickOnceTrustPrompt This will create / or update the current ClickOnce configuration. .NOTES Author: Mötz Jensen (@Splaxi) #> function Set-D365ClickOnceTrustPrompt { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( ) begin { } process { Write-PSFMessage -Level Verbose -Message "Testing if the registry key exists or not" if (-not (Test-Path -Path "HKLM:\SOFTWARE\MICROSOFT\.NETFramework\Security\TrustManager\PromptingLevel")) { Write-PSFMessage -Level Verbose -Message "Registry key was not found. Will create it now." $null = New-Item -Path "HKLM:\SOFTWARE\MICROSOFT\.NETFramework\Security\TrustManager" -Name "PromptingLevel" -Force } Write-PSFMessage -Level Verbose -Message "Setting all necessary registry keys." Set-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\.NETFramework\Security\TrustManager\PromptingLevel" -Name "UntrustedSites" -Type STRING -Value "Disabled" -Force Set-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\.NETFramework\Security\TrustManager\PromptingLevel" -Name "Internet" -Type STRING -Value "Enabled" -Force Set-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\.NETFramework\Security\TrustManager\PromptingLevel" -Name "MyComputer" -Type STRING -Value "Enabled" -Force Set-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\.NETFramework\Security\TrustManager\PromptingLevel" -Name "LocalIntranet" -Type STRING -Value "Enabled" -Force Set-ItemProperty -Path "HKLM:\SOFTWARE\MICROSOFT\.NETFramework\Security\TrustManager\PromptingLevel" -Name "TrustedSites" -Type STRING -Value "Enabled" -Force } end { } } ================================================ FILE: d365fo.tools/functions/set-d365defaultmodelfornewprojects.ps1 ================================================  <# .SYNOPSIS Set the default model used creating new projects in Visual Studio .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 It will backup the current "DynamicsDevConfig.xml" file, for you to revert the changes if anything should go wrong .PARAMETER Module 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 .EXAMPLE PS C:\> Set-D365DefaultModelForNewProjects -Model "FleetManagement" This will update the current default module registered in the "DynamicsDevConfig.xml" file. This file is located in Documents\Visual Studio Dynamics 365\ or in Documents\Visual Studio 2015\Settings\ depending on the version. It will backup the current "DynamicsDevConfig.xml" file. It will replace the value inside the "DefaultModelForNewProjects" tag. .NOTES Tag: Model, Models, Development, Default Model, Module, Project Author: Mötz Jensen (@Splaxi) The work for this cmdlet / function was inspired by Robin Kretzschmar (@DarkSmile92) blog post about changing the default model. The direct link for his blog post is: https://robscode.onl/d365-set-default-model-for-new-projects/ His main blog can found here: https://robscode.onl/ #> function Set-D365DefaultModelForNewProjects { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)] [Alias('Model')] [string] $Module ) begin { $filePath = "$env:UserProfile\Documents\Visual Studio Dynamics 365\DynamicsDevConfig.xml" if (-not (Test-PathExists -Path $filePath -Type Leaf)) { $filePath = "$env:UserProfile\Documents\Visual Studio 2015\Settings\DynamicsDevConfig.xml" } if (-not (Test-PathExists -Path $filePath -Type Leaf)) { return } } process { if (Test-PSFFunctionInterrupt) { return } Backup-D365DevConfig $namespace = @{ns = "http://schemas.microsoft.com/dynamics/2012/03/development/configuration" } $xmlDoc = [xml] (Get-Content -Path $filePath) $defaultModel = Select-Xml -Xml $xmlDoc -XPath "/ns:DynamicsDevConfig/ns:DefaultModelForNewProjects" -Namespace $namespace $oldValue = $defaultModel.Node.InnerText Write-PSFMessage -Level Verbose -Message "Old value found in the file was: $oldValue" -Target $oldValue $defaultModel.Node.InnerText = $Module $xmlDoc.Save($filePath) } end { Get-D365DefaultModelForNewProjects } } ================================================ FILE: d365fo.tools/functions/set-d365favoritebookmark.ps1 ================================================  <# .SYNOPSIS Enable the favorite bar and add an URL .DESCRIPTION Enable the favorite bar in Edge & Chrome and put in the URL as a favorite/bookmark .PARAMETER URL The URL of the shortcut you want to add to the favorite bar .PARAMETER D365FO Instruct the cmdlet that you want the populate the D365FO favorite entry based on the URL provided .PARAMETER AzureDevOps Instruct the cmdlet that you want the populate the AzureDevOps favorite entry based on the URL provided .EXAMPLE PS C:\> Set-D365FavoriteBookmark -Url "https://usnconeboxax1aos.cloud.onebox.dynamics.com" This will add the "https://usnconeboxax1aos.cloud.onebox.dynamics.com" to the favorite bar, enable the favorite bar and lock it. This will be interpreted as the using the -D365FO parameter also, because that is the expected behavior. .EXAMPLE PS C:\> Set-D365FavoriteBookmark -Url "https://usnconeboxax1aos.cloud.onebox.dynamics.com" -D365FO This will add the "https://usnconeboxax1aos.cloud.onebox.dynamics.com" to the favorite bar, enable the favorite bar and lock it. The bookmark will be mapped as the one for the Dynamics 365 Finance & Operations instance. .EXAMPLE PS C:\> Set-D365FavoriteBookmark -Url "https://CUSTOMERNAME.visualstudio.com/" -AzureDevOps This will add the "https://CUSTOMERNAME.visualstudio.com/" to the favorite bar, enable the favorite bar and lock it. The bookmark will be mapped as the one for the Azure DevOps instance. .EXAMPLE PS C:\> Get-D365Url | Set-D365FavoriteBookmark This will get the URL from the environment and add that to the favorite bar, enable the favorite bar and lock it. This will be interpreted as the using the -D365FO parameter also, because that is the expected behavior. .NOTES Author: Mötz Jensen (@Splaxi) #> function Set-D365FavoriteBookmark { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding(DefaultParameterSetName = "D365FO")] param ( [Parameter(ValueFromPipelineByPropertyName = $true)] [string] $URL, [Parameter(Mandatory = $false, ParameterSetName = "D365FO")] [switch] $D365FO, [Parameter(Mandatory = $false, ParameterSetName = "AzureDevOps")] [switch] $AzureDevOps ) begin { } process { if ($PSCmdlet.ParameterSetName -eq "D365FO") { $name = "D365FO" } else { $name = "AzureDevOps" } # Is edge installed? $pathEdgeBase = "$($env:LOCALAPPDATA)\Microsoft\Edge\User Data\Default" if (Test-PathExists -Path $pathEdgeBase -Type Container) { Set-BrowserBookmark -PathBrowser $pathEdgeBase -Uri $URL -Name $name } # Is chrome installed? $pathChromeBase = "$($env:LOCALAPPDATA)\Google\Chrome\User Data\Default" if (Test-PathExists -Path $pathChromeBase -Type Container) { Set-BrowserBookmark -PathBrowser $pathChromeBase -Uri $URL -Name $name } } end { } } ================================================ FILE: d365fo.tools/functions/set-d365flightservicecatalogid.ps1 ================================================  <# .SYNOPSIS Set the FlightingServiceCatalogID .DESCRIPTION Set the FlightingServiceCatalogID element in the web.config file used by D365FO .PARAMETER AosServiceWebRootPath Path to the root folder where to locate the web.config file .PARAMETER FlightServiceCatalogId Flighting catalog ID to be set .EXAMPLE PS C:\> Set-D365FlightServiceCatalogId This will set the FlightingServiceCatalogID element the web.config to the default value "12719367". .NOTES Tags: Flight, Flighting Author: Frank Hüther(@FrankHuether)) The DataAccess.FlightingServiceCatalogID element must already exist in the web.config file, which is expected to be the case in newer environments. 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 #> function Set-D365FlightServiceCatalogId { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [string]$FlightServiceCatalogId = "12719367", [string]$AosServiceWebRootPath = $Script:AOSPath ) try { $WebConfigFile = Join-Path -Path $AosServiceWebRootPath -ChildPath $Script:WebConfig Write-PSFMessage -Level Verbose -Message "Retrieve the FlightingServiceCatalogID" -Target $WebConfigFile [xml]$WebConfigContents = Get-Content $WebConfigFile $FlightServiceNode = $WebConfigContents.SelectSingleNode("/configuration/appSettings/add[@key='DataAccess.FlightingServiceCatalogID']/@value") if($null -eq $FlightServiceNode){ Write-PSFMessage -Level Host -Message "The DataAccess.FlightingServiceCatalogID child element under the AppSettings element is missing. 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." Stop-PSFFunction -Message "Stopping because of errors" return } $FlightServiceNode.Value = $FlightServiceCatalogId Write-PSFMessage -Level Verbose -Message "Write the FlightingServiceCatalogID" -Target $WebConfigFile $WebConfigContents.Save($WebConfigFile) Write-PSFMessage -Level Verbose -Message "New FlightingServiceCatalogID: $($FlightServiceNode.Value)" -Target $WebConfigFile } catch { Write-PSFMessage -Level Host -Message "Something went wrong while updating the web.config file" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } ================================================ FILE: d365fo.tools/functions/set-d365lcsapiconfig.ps1 ================================================  <# .SYNOPSIS Set the LCS configuration details .DESCRIPTION Set the LCS configuration details and save them into the configuration store .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER ClientId The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER ActiveTokenExpiresOn The point in time where the current bearer token will expire The time is measured in Unix Time, total seconds since 1970-01-01 .PARAMETER RefreshToken The Refresh Token that you want to use for the authentication process .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER Temporary Instruct the cmdlet to only temporarily override the persisted settings in the configuration storage .EXAMPLE PS C:\> Set-D365LcsApiConfig -ProjectId 123456789 -ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" -BearerToken "JldjfafLJdfjlfsalfd..." -ActiveTokenExpiresOn 1556909205 -RefreshToken "Tsdljfasfe2j32324" -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will set the LCS API configuration. The ProjectId 123456789 will be saved as the default ProjectId for all cmdlets that will interact with LCS, if they require a ProjectId. 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. 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. The ActiveTokenExpiresOn 1556909205 will be saved to assist the module in determine whether the BearerToken is still valid or not. The RefreshToken "Tsdljfasfe2j32324" will be saved as the default RefreshToken for all cmdlets that will interact with tokens. The LcsApiUri "https://lcsapi.lcs.dynamics.com" will be saved as the default LCS HTTP endpoint for all cmdlets that will interact with LCS. .EXAMPLE PS C:\> Get-D365LcsApiToken -Username "serviceaccount@domain.com" -Password "TopSecretPassword" | Set-D365LcsApiConfig This will obtain a valid OAuth 2.0 access token from Azure Active Directory and save the needed details. 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". The output object received from Get-D365LcsApiToken is piped directly to Set-D365LcsApiConfig. Set-D365LcsApiConfig will save the access_token(BearerToken), refresh_token(RefreshToken) and expires_on(ActiveTokenExpiresOn). These values will then be available as default values for all LCS cmdlets across the module. You can validate the current default values by calling Get-D365LcsApiConfig. .NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, ClientId Author: Mötz Jensen (@Splaxi) #> function Set-D365LcsApiConfig { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] [OutputType()] param( [int] $ProjectId, [string] $ClientId, [Parameter(ValueFromPipelineByPropertyName = $true)] [Alias('access_token')] [Alias('AccessToken')] [string] $BearerToken, [Parameter(ValueFromPipelineByPropertyName = $true)] [Alias('expires_on')] [long] $ActiveTokenExpiresOn, [Parameter(ValueFromPipelineByPropertyName = $true)] [Alias('refresh_token')] [string] $RefreshToken, [Parameter(ValueFromPipelineByPropertyName = $true)] [Alias('resource')] [string] $LcsApiUri = "https://lcsapi.lcs.dynamics.com", [switch] $Temporary ) process { #The ':keys' label is used to have a continue inside the switch statement itself :keys foreach ($key in $PSBoundParameters.Keys) { $configurationValue = $PSBoundParameters.Item($key) $configurationName = $key.ToLower() $fullConfigName = "" Write-PSFMessage -Level Verbose -Message "Working on $key with $configurationValue" -Target $configurationValue switch ($key) { "Temporary" { continue keys } Default { $fullConfigName = "d365fo.tools.lcs.$configurationName" } } Write-PSFMessage -Level Verbose -Message "Setting $fullConfigName to $configurationValue" -Target $configurationValue Set-PSFConfig -FullName $fullConfigName -Value $configurationValue if (-not $Temporary) { Register-PSFConfig -FullName $fullConfigName -Scope UserDefault } } Update-LcsApiVariables } } ================================================ FILE: d365fo.tools/functions/set-d365nugetpath.ps1 ================================================  <# .SYNOPSIS Set the path for nuget.exe .DESCRIPTION Update the path where the module will be looking for the nuget.exe executable .PARAMETER Path Path to the nuget.exe .EXAMPLE PS C:\> Set-D365NugetPath -Path "C:\temp\d365fo.tools\nuget\nuget.exe" This will update the path for the nuget.exe in the modules configuration .NOTES Author: Mötz Jensen (@Splaxi) #> function Set-D365NugetPath { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] [OutputType()] param ( [Parameter(Mandatory = $true)] [string] $Path ) if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } Set-PSFConfig -FullName "d365fo.tools.path.nuget" -Value $Path Register-PSFConfig -FullName "d365fo.tools.path.nuget" Update-ModuleVariables } ================================================ FILE: d365fo.tools/functions/set-d365offlineauthenticationadminemail.ps1 ================================================  <# .SYNOPSIS Sets the offline administrator e-mail .DESCRIPTION Sets the registered offline administrator in the "DynamicsDevConfig.xml" file located in the default Package Directory .PARAMETER Email The desired email address of the to be offline administrator .EXAMPLE PS C:\> Set-D365OfflineAuthenticationAdminEmail -Email "admin@contoso.com" Will update the Offline Administrator E-mail address in the DynamicsDevConfig.xml file with "admin@contoso.com" .NOTES This cmdlet is inspired by the work of "Sheikh Sohail Hussain" (twitter: @SSohailHussain) His blog can be found here: http://d365technext.blogspot.com The specific blog post that we based this cmdlet on can be found here: http://d365technext.blogspot.com/2018/07/offline-authentication-admin-email.html Author: Mötz Jensen (@Splaxi) #> function Set-D365OfflineAuthenticationAdminEmail { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 1 )] [string] $Email ) if (-not ($script:IsAdminRuntime)) { Write-PSFMessage -Level Host -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." Stop-PSFFunction -Message "Stopping because the function is not run elevated" return } $filePath = Join-Path (Join-Path $Script:PackageDirectory "bin") "DynamicsDevConfig.xml" if (-not (Test-PathExists -Path $filePath -Type Leaf)) {return} $namespace = @{ns="http://schemas.microsoft.com/dynamics/2012/03/development/configuration"} $xmlDoc = [xml] (Get-Content -Path $filePath) $OfflineAuthAdminEmail = Select-Xml -Xml $xmlDoc -XPath "/ns:DynamicsDevConfig/ns:OfflineAuthenticationAdminEmail" -Namespace $namespace $oldValue = $OfflineAuthAdminEmail.Node.InnerText Write-PSFMessage -Level Verbose -Message "Old value found in the file was: $oldValue" -Target $oldValue $OfflineAuthAdminEmail.Node.InnerText = $Email $xmlDoc.Save($filePath) } ================================================ FILE: d365fo.tools/functions/set-d365rsatconfiguration.ps1 ================================================  <# .SYNOPSIS Set different RSAT configuration values .DESCRIPTION Update different RSAT configuration values while using the tool .PARAMETER LogGenerationEnabled Will set the LogGeneration property $true will make RSAT start generating logs $false will stop RSAT from generating logs .PARAMETER VerboseSnapshotsEnabled Will set the VerboseSnapshotsEnabled property $true will make RSAT start generating snapshots and store related details $false will stop RSAT from generating snapshots and store related details .PARAMETER AddOperatorFieldsToExcelValidationEnabled Will set the AddOperatorFieldsToExcelValidation property $true will make RSAT start adding the operation options in the excel parameter file $false will stop RSAT from adding the operation options in the excel parameter file .PARAMETER RSATConfigFilename Specifies the file name of the RSAT configuration file. Default is 'Microsoft.Dynamics.RegressionSuite.WpfApp.exe.config' If you are using an older version of RSAT, you might need to change this to 'Microsoft.Dynamics.RegressionSuite.WindowsApp.exe.config' .EXAMPLE PS C:\> Set-D365RsatConfiguration -LogGenerationEnabled $true This will enable the log generation logic of RSAT. .EXAMPLE PS C:\> Set-D365RsatConfiguration -VerboseSnapshotsEnabled $true This will enable the snapshot generation logic of RSAT. .EXAMPLE PS C:\> Set-D365RsatConfiguration -AddOperatorFieldsToExcelValidationEnabled $true This will enable the operator generation logic of RSAT. .NOTES Tags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, Configuration Author: Mötz Jensen (@Splaxi) #> function Set-D365RsatConfiguration { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] [OutputType()] param ( [Parameter(Mandatory = $false)] [bool] $LogGenerationEnabled, [Parameter(Mandatory = $false)] [bool] $VerboseSnapshotsEnabled, [Parameter(Mandatory = $false)] [bool] $AddOperatorFieldsToExcelValidationEnabled, [Parameter(Mandatory = $false)] $RSATConfigFilename = "Microsoft.Dynamics.RegressionSuite.WpfApp.exe.config" ) $configPath = Join-Path $Script:RsatPath $RSATConfigFilename if (-not (Test-PathExists -Path $configPath -Type Leaf)) { Write-PSFMessage -Level Critical -Message "The '$RSATConfigFilename' file could not be found on the system." Stop-PSFFunction -Message "Stopping because the '$RSATConfigFilename' file could not be located." return } try { [xml]$xmlConfig = Get-Content $configPath if ($PSBoundParameters.Keys -contains "LogGenerationEnabled") { $logGenerationAttribute = $xmlConfig.SelectNodes('//appSettings//add[@key="LogGeneration"]') if ($logGenerationAttribute) { $logGenerationAttribute.SetAttribute('value', $LogGenerationEnabled.ToString().ToLower()) } } if ($PSBoundParameters.Keys -contains "VerboseSnapshotsEnabled") { $verboseSnapshotsAttribute = $xmlConfig.SelectNodes('//appSettings//add[@key="VerboseSnapshotsEnabled"]') if ($verboseSnapshotsAttribute) { $verboseSnapshotsAttribute.SetAttribute('value', $VerboseSnapshotsEnabled.ToString().ToLower()) } } if ($PSBoundParameters.Keys -contains "AddOperatorFieldsToExcelValidationEnabled") { $addOperatorFieldsToExcelValidationAttribute = $xmlConfig.SelectNodes('//appSettings//add[@key="AddOperatorFieldsToExcelValidation"]') if ($addOperatorFieldsToExcelValidationAttribute) { $addOperatorFieldsToExcelValidationAttribute.SetAttribute('value', $AddOperatorFieldsToExcelValidationEnabled.ToString().ToLower()) } } $xmlConfig.Save($configPath) } catch { Write-PSFMessage -Level Host -Message "Something went wrong while updating the RSAT configuration file" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } ================================================ FILE: d365fo.tools/functions/set-d365rsattier2crypto.ps1 ================================================  <# .SYNOPSIS Set the needed configuration to work on Tier2+ environments .DESCRIPTION Set the needed registry settings for when you are running RSAT against a Tier2+ environment .EXAMPLE PS C:\> Set-D365RsatTier2Crypto This will configure the registry to support RSAT against a Tier2+ environment. .NOTES Tags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, Configuration Author: Mötz Jensen (@Splaxi) #> function Set-D365RsatTier2Crypto { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] [OutputType()] param () if ((Test-Path "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319")) { Set-ItemProperty "HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319" -Name SchUseStrongCrypto -Value 1 -Type dword -Force -Confirm:$false } } ================================================ FILE: d365fo.tools/functions/set-d365sdpcleanup.ps1 ================================================  <# .SYNOPSIS Set the cleanup retention period .DESCRIPTION Sets the configured retention period before updates are deleted .PARAMETER NumberOfDays Number of days that deployable software packages should remain on the server .EXAMPLE PS C:\> Set-D365SDPCleanUp -NumberOfDays 10 This will set the retention period to 10 days inside the the registry The cmdlet REQUIRES elevated permissions to run, otherwise it will fail .NOTES This cmdlet is based on the findings from Alex Kwitny (@AlexOnDAX) See his blog for more info: http://www.alexondax.com/2018/04/msdyn365fo-how-to-adjust-your.html Author: Mötz Jensen (@Splaxi) #> function Set-D365SDPCleanUp { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [int] $NumberOfDays = 30 ) if (-not ($Script:IsAdminRuntime)) { Write-PSFMessage -Level Host -Message "It seems that you ran this cmdlet non-elevated. 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`"" Stop-PSFFunction -Message "Stopping because of missing parameters" return } Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Dynamics\Deployment" -Name "CutoffDaysForCleanup" -Type STRING -Value "$NumberOfDays" -Force } ================================================ FILE: d365fo.tools/functions/set-d365sqlpackagepath.ps1 ================================================  <# .SYNOPSIS Set the path for SqlPackage.exe .DESCRIPTION Update the path where the module will be looking for the SqlPackage.exe executable .PARAMETER Path Path to the SqlPackage.exe .EXAMPLE PS C:\> Set-D365SqlPackagePath -Path "C:\Program Files\Microsoft SQL Server\150\DAC\bin\SqlPackage.exe" This will update the path for the SqlPackage.exe in the modules configuration .NOTES Author: Mötz Jensen (@Splaxi) #> function Set-D365SqlPackagePath { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] [OutputType()] param ( [Parameter(Mandatory = $true)] [string] $Path ) if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } Set-PSFConfig -FullName "d365fo.tools.path.sqlpackage" -Value $Path Register-PSFConfig -FullName "d365fo.tools.path.sqlpackage" Update-ModuleVariables } ================================================ FILE: d365fo.tools/functions/set-d365startpage.ps1 ================================================  <# .SYNOPSIS Sets the start page in internet explorer .DESCRIPTION Function for setting the start page in internet explorer .PARAMETER Name Name of the D365 Instance .PARAMETER Url URL of the D365 for Finance & Operations instance that you want to have as your start page .EXAMPLE PS C:\> Set-D365StartPage -Name 'Demo1' This will update the start page for the current user to "https://Demo1.cloud.onebox.dynamics.com" .EXAMPLE PS C:\> Set-D365StartPage -URL "https://uat.sandbox.operations.dynamics.com" This will update the start page for the current user to "https://uat.sandbox.operations.dynamics.com" .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Set-D365StartPage() { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding(DefaultParameterSetName = 'Default')] param( [Parameter(Mandatory = $true, Position = 1, ParameterSetName = 'Default')] [String] $Name, [Parameter(Mandatory = $true, Position = 1, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'Url')] [String] $Url ) process { $path = 'HKCU:\Software\Microsoft\Internet Explorer\Main\' $propName = 'start page' if ($PSBoundParameters.ContainsKey("URL")) { $value = $Url } else { $value = "https://$Name.cloud.onebox.dynamics.com" } Set-Itemproperty -Path $path -Name $propName -Value $value } } ================================================ FILE: d365fo.tools/functions/set-d365sysadmin.ps1 ================================================  <# .SYNOPSIS Set a user to sysadmin .DESCRIPTION Set a user to sysadmin inside the SQL Server .PARAMETER User The user that you want to make sysadmin Most be well formatted server\user or domain\user. Default value is: machinename\administrator .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .EXAMPLE PS C:\> Set-D365SysAdmin This will configure the local administrator on the machine as a SYSADMIN inside SQL Server For this to run you need to be running it from a elevated console .EXAMPLE PS C:\> Set-D365SysAdmin -SqlPwd Test123 This will configure the local administrator on the machine as a SYSADMIN inside SQL Server. It will logon as the default SqlUser but use the provided SqlPwd. This can be run from a non-elevated console .NOTES Author: Mötz Jensen (@splaxi) #> function Set-D365SysAdmin { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 1)] [string] $User = "$env:computername\administrator", [Parameter(Mandatory = $false, Position = 2)] [string] $DatabaseServer = $Script:DatabaseServer, [Parameter(Mandatory = $false, Position = 3)] [string] $DatabaseName = $Script:DatabaseName, [Parameter(Mandatory = $false, Position = 4)] [string] $SqlUser = $Script:DatabaseUserName, [Parameter(Mandatory = $false, Position = 5)] [string] $SqlPwd = $Script:DatabaseUserPassword ) $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } Write-PSFMessage -Level Debug -Message "Testing if running either elevated or with -SqlPwd set." if ((-not ($script:IsAdminRuntime)) -and (-not ($PSBoundParameters.ContainsKey("SqlPwd")))) { Write-PSFMessage -Level Host -Message "It seems that you ran this cmdlet non-elevated and without the -SqlPwd parameter. If you don't want to supply the -SqlPwd you must run the cmdlet elevated (Run As Administrator) otherwise simply use the -SqlPwd parameter" Stop-PSFFunction -Message "Stopping because of missing parameters" return } $commandText = (Get-Content "$script:ModuleRoot\internal\sql\set-sysadmin.sql") -join [Environment]::NewLine $commandText = $commandText.Replace('@USER', $User) $sqlCommand = Get-SqlCommand @SqlParams $sqlCommand.CommandText = $commandText try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $null = $sqlCommand.ExecuteNonQuery() } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } } ================================================ FILE: d365fo.tools/functions/set-d365traceparserfilesize.ps1 ================================================  <# .SYNOPSIS Configue a new maximum file size for the TraceParser .DESCRIPTION Change the maximum file size that the TraceParser generates .PARAMETER FileSizeInMB The maximum size that you want to allow the TraceParser file to grow to Original value inside the configuration is 1024 (MB) .PARAMETER Path The path to the TraceParser.config file that you want to edit The default path is: "\AosService\Webroot\Services\TraceParserService\TraceParserService.config" .EXAMPLE PS C:\> Set-D365TraceParserFileSize -FileSizeInMB 2048 This will configure the maximum TraceParser file to 2048 MB. .NOTES Author: Mötz Jensen (@Splaxi) #> function Set-D365TraceParserFileSize { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $FileSizeInMB, [string] $Path = (Join-Path $Script:AOSPath "Services\TraceParserService\TraceParserService.config") ) if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } $xmlDoc = [xml] (Get-Content -Path $Path) $fileSize = Select-Xml -Xml $xmlDoc -XPath "/Microsoft.Dynamics.AX.Services.Tracing.TraceParser.Properties.Settings/setting[@name='MaximumEtlFileSizeInMb']/value" $fileSize.Node."#text" = "$FileSizeInMB" $xmlDoc.Save($Path) } ================================================ FILE: d365fo.tools/functions/set-d365webconfigdatabase.ps1 ================================================  <# .SYNOPSIS Set the database connection details .DESCRIPTION Overwrite the current database connection details directly in the web.config file 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 .PARAMETER DatabaseServer The name of the database server Obtain when you request JIT (Just-in-Time) access through the LCS portal .PARAMETER DatabaseName The name of the database Obtain when you request JIT (Just-in-Time) access through the LCS portal .PARAMETER SqlUser The login name for the SQL Server instance Obtain when you request JIT (Just-in-Time) access through the LCS portal .PARAMETER SqlPwd The password for the SQL Server user Obtain when you request JIT (Just-in-Time) access through the LCS portal .PARAMETER Path Path to the web.config file that you want to update with new SQL connection details Default is: "K:\AosService\WebRoot\web.config" or what else drive that is recognized by the D365FO components as the service drive .EXAMPLE PS C:\> Set-D365WebConfigDatabase -DatabaseServer TestServer.database.windows.net -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" Will overwrite Server, Database, Username and Password directly in the web.config file. It will save all details unencrypted. .NOTES Tags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB Author: Mötz Jensen (@Splaxi) #> function Set-D365WebConfigDatabase { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $DatabaseServer, [Parameter(Mandatory = $true)] [string] $DatabaseName, [Parameter(Mandatory = $true)] [string] $SqlUser, [Parameter(Mandatory = $true)] [string] $SqlPwd, $Path = $(Join-Path -Path $Script:AOSPath -ChildPath $Script:WebConfig) ) begin { if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False } process { $content = Get-Content -Path $Path -Raw $content = $content -replace '', $('' -f "$DatabaseName") $content = $content -replace '', $('' -f "$DatabaseServer") $content = $content -replace '', $('' -f "$SqlPwd") $content = $content -replace '', $('' -f "$SqlUser") [System.IO.File]::WriteAllText($Path, $content, $Utf8NoBomEncoding) } } ================================================ FILE: d365fo.tools/functions/set-d365webservertype.ps1 ================================================  <# .SYNOPSIS Set the web server type to be used to run the D365FO instance .DESCRIPTION Set the web server which will be used to run D365FO: Either IIS or IIS Express. Newly deployed development machines will have this set to IIS Express by default. It will backup the current "DynamicsDevConfig.xml" file, for you to revert the changes if anything should go wrong. It will look for the file located in the default Package Directory. .PARAMETER RuntimeHostType The type of web server you want to use. Valid options are: "IIS" "IISExpress" .EXAMPLE PS C:\> Set-D365WebServerType -RuntimeHostType "IIS" This will update the current web server type registered in the "DynamicsDevConfig.xml" file. This file is located "K:\AosService\PackagesLocalDirectory\bin". It will backup the current "DynamicsDevConfig.xml" file. It will replace the value inside the "RuntimeHostType" tag. .NOTES Tag: Web Server, IIS, IIS Express, Development Author: Sander Holvoet (@smholvoet) Author: Mötz Jensen (@Splaxi) #> function Set-D365WebServerType { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)] [ValidateSet('IIS', 'IISExpress')] [string] $RuntimeHostType ) begin { if (-not ($script:IsAdminRuntime)) { Write-PSFMessage -Level Host -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." Stop-PSFFunction -Message "Stopping because the function is not run elevated" return } $filePath = Join-Path -Path (Join-Path -Path $Script:PackageDirectory -ChildPath "bin") -ChildPath $Script:DevConfig if (-not (Test-PathExists -Path $filePath -Type Leaf)) { return } } process { if (Test-PSFFunctionInterrupt) { return } $filePathBackup = $filePath.Replace(".xml", ".xml$((Get-Date).Ticks)") Copy-Item -Path $filePath -Destination $filePathBackup -Force $namespace = @{ns = "http://schemas.microsoft.com/dynamics/2012/03/development/configuration" } $xmlDoc = [xml] (Get-Content -Path $filePath) $runtimeHostType = Select-Xml -Xml $xmlDoc -XPath "/ns:DynamicsDevConfig/ns:RuntimeHostType" -Namespace $namespace $oldValue = $runtimeHostType.Node.InnerText Write-PSFMessage -Level Verbose -Message "Old value found in the file was: $oldValue" -Target $oldValue $runtimeHostType.Node.InnerText = $RuntimeHostType $xmlDoc.Save($filePath) } end { Get-D365WebServerType } } ================================================ FILE: d365fo.tools/functions/set-d365workstationmode.ps1 ================================================  <# .SYNOPSIS Set the Workstation mode .DESCRIPTION Set the Workstation mode to enabled or not It is used to enable the tool to run on a personal machine and still be able to call Invoke-D365TableBrowser and Invoke-D365SysRunnerClass .PARAMETER Enabled $True enables the workstation mode while $false deactivated the workstation mode .EXAMPLE PS C:\> Set-D365WorkstationMode -Enabled $true This will enable the Workstation mode. You will have to restart the powershell session when you switch around. .NOTES Author: Mötz Jensen (@Splaxi) You will have to run the Initialize-D365Config cmdlet first, before this will be capable of working. #> function Set-D365WorkstationMode { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [boolean] $Enabled ) Set-PSFConfig -FullName "d365fo.tools.workstation.mode" -Value $Enabled Register-PSFConfig -FullName "d365fo.tools.workstation.mode" Write-PSFMessage -Level Host -Message "Please restart the powershell session / console. This change affects core functionality that requires the module to be reloaded." } ================================================ FILE: d365fo.tools/functions/start-d365environment.ps1 ================================================  <# .SYNOPSIS Cmdlet to start the different services in a Dynamics 365 Finance & Operations environment .DESCRIPTION Can start all relevant services that is running in a D365FO environment .PARAMETER ComputerName An array of computers that you want to start services on. .PARAMETER All Set when you want to start all relevant services Includes: Aos Batch Financial Reporter .PARAMETER Aos Start the Aos (iis) service .PARAMETER Batch Start the batch service .PARAMETER FinancialReporter Start the financial reporter (Management Reporter 2012) service .PARAMETER DMF Start the Data Management Framework service .PARAMETER OnlyStartTypeAutomatic Instruct the cmdlet to filter out services that are set to manual start or disabled .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .EXAMPLE PS C:\> Start-D365Environment This will run the cmdlet with the default parameters. Default is "-All". This will start all D365FO services on the machine. .EXAMPLE PS C:\> Start-D365Environment -OnlyStartTypeAutomatic This will start all D365FO services on the machine that are configured for Automatic startup. It will exclude all services that are either manual or disabled in their startup configuration. .EXAMPLE PS C:\> Start-D365Environment -ShowOriginalProgress This will run the cmdlet with the default parameters. Default is "-All". This will start all D365FO services on the machine. The progress of starting the different services will be written to the console / host. .EXAMPLE PS C:\> Start-D365Environment -All This will start all D365FO services on the machine. .EXAMPLE PS C:\> Start-D365Environment -Aos -Batch This will start the Aos & Batch D365FO services on the machine. .EXAMPLE PS C:\> Start-D365Environment -FinancialReporter -DMF This will start the FinancialReporter and DMF services on the machine. .NOTES Author: Mötz Jensen (@Splaxi) #> function Start-D365Environment { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueSwitchParameter", "")] [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )] [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 1 )] [string[]] $ComputerName = @($env:computername), [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )] [switch] $All = $true, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 2 )] [switch] $Aos, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 3 )] [switch] $Batch, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 4 )] [switch] $FinancialReporter, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 5 )] [switch] $DMF, [switch] $OnlyStartTypeAutomatic, [switch] $ShowOriginalProgress ) Import-Module -Name "WebAdministration" -Scope "Local" if ($PSCmdlet.ParameterSetName -eq "Specific") { $All = $false } if ( (-not ($All)) -and (-not ($Aos)) -and (-not ($Batch)) -and (-not ($FinancialReporter)) -and (-not ($DMF))) { Write-PSFMessage -Level Host -Message "You have to use at least one switch when running this cmdlet. Please run the cmdlet again." Stop-PSFFunction -Message "Stopping because of missing parameters" return } $warningActionValue = "SilentlyContinue" if ($ShowOriginalProgress) { $warningActionValue = "Continue" } $Params = Get-DeepClone $PSBoundParameters if ($Params.ContainsKey("ComputerName")) { $null = $Params.Remove("ComputerName") } if ($Params.ContainsKey("ShowOriginalProgress")) { $null = $Params.Remove("ShowOriginalProgress") } if ($Params.ContainsKey("OnlyStartTypeAutomatic")) { $null = $Params.Remove("OnlyStartTypeAutomatic") } $Services = Get-ServiceList @Params $Results = foreach ($server in $ComputerName) { Write-PSFMessage -Level Verbose -Message "Working against: $server - starting services" $temp = Get-Service -ComputerName $server -Name $Services -ErrorAction SilentlyContinue if ($OnlyStartTypeAutomatic) { $temp = $temp | Where-Object StartType -eq "Automatic" } $temp | Start-Service -ErrorAction SilentlyContinue -WarningAction $warningActionValue if ($server -eq $env:computername -and ($($temp -join ",") -like "*w3svc*")) { Start-Website -Name "AOSService" } } $Results = foreach ($server in $ComputerName) { Write-PSFMessage -Level Verbose -Message "Working against: $server - listing services" $temp = Get-Service -ComputerName $server -Name $Services -ErrorAction SilentlyContinue if ($OnlyStartTypeAutomatic) { $temp = $temp | Where-Object StartType -eq "Automatic" } $temp | Select-Object @{Name = "Server"; Expression = { $Server } }, Name, Status, StartType, DisplayName } Write-PSFMessage -Level Verbose "Results are: $Results" -Target ($Results.Name -join ",") $Results | Select-PSFObject -TypeName "D365FO.TOOLS.Environment.Service" Server, DisplayName, Status, StartType, Name } ================================================ FILE: d365fo.tools/functions/start-d365environmentv2.ps1 ================================================  <# .SYNOPSIS Cmdlet to start the different services in a Dynamics 365 Finance & Operations environment .DESCRIPTION Can start all relevant services that is running in a D365FO environment .PARAMETER All Set when you want to start all relevant services Includes: Aos Batch Financial Reporter Data Management Framework .PARAMETER Aos Start the Aos (iis) service .PARAMETER Batch Start the batch service .PARAMETER FinancialReporter Start the financial reporter (Management Reporter 2012) service .PARAMETER DMF Start the Data Management Framework service .PARAMETER OnlyStartTypeAutomatic Instruct the cmdlet to filter out services that are set to manual start or disabled .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .EXAMPLE PS C:\> Start-D365EnvironmentV2 This will run the cmdlet with the default parameters. Default is "-All". This will start all D365FO services on the machine. .EXAMPLE PS C:\> Start-D365EnvironmentV2 -OnlyStartTypeAutomatic This will start all D365FO services on the machine that are configured for Automatic startup. It will exclude all services that are either manual or disabled in their startup configuration. .EXAMPLE PS C:\> Start-D365EnvironmentV2 -ShowOriginalProgress This will run the cmdlet with the default parameters. Default is "-All". This will start all D365FO services on the machine. The progress of starting the different services will be written to the console / host. .EXAMPLE PS C:\> Start-D365EnvironmentV2 -All This will start all D365FO services on the machine. .EXAMPLE PS C:\> Start-D365EnvironmentV2 -Aos -Batch This will start the Aos & Batch D365FO services on the machine. .EXAMPLE PS C:\> Start-D365EnvironmentV2 -FinancialReporter -DMF This will start the FinancialReporter and DMF services on the machine. .EXAMPLE PS C:\> Enable-D365Exception PS C:\> Start-D365EnvironmentV2 This will run the cmdlet with the default parameters. Default is "-All". This will start all D365FO services on the machine. If a service does not start, it will throw an exception. .NOTES Author: Vincent Verweij (@VincentVerweij) #> function Start-D365EnvironmentV2 { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueSwitchParameter", "")] [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )] [switch] $All = $true, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 1 )] [switch] $Aos, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 2 )] [switch] $Batch, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 3 )] [switch] $FinancialReporter, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 4 )] [switch] $DMF, [switch] $OnlyStartTypeAutomatic, [switch] $ShowOriginalProgress ) Import-Module -Name "WebAdministration" -Scope "Local" if ($PSCmdlet.ParameterSetName -eq "Specific") { $All = $false } if ( (-not ($All)) -and (-not ($Aos)) -and (-not ($Batch)) -and (-not ($FinancialReporter)) -and (-not ($DMF))) { Write-PSFMessage -Level Host -Message "You have to use at least one switch when running this cmdlet. Please run the cmdlet again." Stop-PSFFunction -Message "Stopping because of missing parameters" return } $ComputerName = @($env:computername) $warningActionValue = "SilentlyContinue" if ($ShowOriginalProgress) { $warningActionValue = "Continue" } $Params = Get-DeepClone $PSBoundParameters if ($Params.ContainsKey("ShowOriginalProgress")) { $null = $Params.Remove("ShowOriginalProgress") } if ($Params.ContainsKey("OnlyStartTypeAutomatic")) { $null = $Params.Remove("OnlyStartTypeAutomatic") } $psItemExceptionsFromStartServices = New-Object -TypeName "System.Collections.ArrayList" $didServiceStartThrowException = $false $Services = Get-ServiceList @Params Write-PSFMessage -Level Verbose -Message "Working against: $ComputerName - starting services" $temp = Get-Service -ComputerName $ComputerName -Name $Services -ErrorAction SilentlyContinue if ($OnlyStartTypeAutomatic) { $temp = $temp | Where-Object StartType -eq "Automatic" } try { $temp | Start-Service -WarningAction $warningActionValue } catch { $didServiceStartThrowException = $true $psItemExceptionsFromStartServices.Add($PSItem.Exception) } if (($($temp -join ",") -like "*w3svc*")) { Start-Website -Name "AOSService" } Write-PSFMessage -Level Verbose -Message "Working against: $ComputerName - listing services" $temp = Get-Service -ComputerName $ComputerName -Name $Services -ErrorAction SilentlyContinue if ($OnlyStartTypeAutomatic) { $temp = $temp | Where-Object StartType -eq "Automatic" } $Results = $temp | Select-Object @{Name = "Server"; Expression = { $ComputerName } }, Name, Status, StartType, DisplayName Write-PSFMessage -Level Verbose "Results are: $Results" -Target ($Results.Name -join ",") $Results | Select-PSFObject -TypeName "D365FO.TOOLS.Environment.Service" Server, DisplayName, Status, StartType, Name if ($didServiceStartThrowException) { foreach ($psItemException in $psItemExceptionsFromStartServices) { Write-PSFMessage -Level Host -Message "Something went wrong while starting the service(s) on computer '$($ComputerName)'" -Exception $psItemException } } } ================================================ FILE: d365fo.tools/functions/start-d365eventtrace.ps1 ================================================  <# .SYNOPSIS Start an Event Trace session .DESCRIPTION Start an Event Trace session with default values to help you getting started .PARAMETER ProviderName Name of the provider(s) you want to have part of your trace Accepts an array/list of provider names .PARAMETER OutputPath Path to the output folder where you want to store the ETL file that will be generated Default path is "C:\Temp\d365fo.tools\EventTrace" .PARAMETER SessionName Name that you want the tracing session to have while running the trace Default value is "d365fo.tools.trace" .PARAMETER FileName Name of the file that you want the trace to write its output to Default value is "d365fo.tools.trace.etl" .PARAMETER OutputFormat The desired output format of the ETL file being outputted from the tracing session Default value is "bincirc" .PARAMETER MinBuffer The minimum buffer size in MB that you want the tracing session to work with Default value is 10240 .PARAMETER MaxBuffer The maximum buffer size in MB that you want the tracing session to work with Default value is 10240 .PARAMETER BufferSizeKB The buffer size in KB that you want the tracing session to work with Default value is 1024 .PARAMETER MaxLogFileSizeMB The maximum log file size in MB that you want the tracing session to work with Default value is 4096 .EXAMPLE PS C:\> Start-D365EventTrace -ProviderName "Microsoft-Dynamics-AX-FormServer","Microsoft-Dynamics-AX-XppRuntime" This will start a new Event Tracing session with the binary circular output format. It uses "Microsoft-Dynamics-AX-FormServer","Microsoft-Dynamics-AX-XppRuntime" as the providernames. It uses the default output folder "C:\Temp\d365fo.tools\EventTrace". It will use the default values for the remaining parameters. .EXAMPLE PS C:\> Start-D365EventTrace -ProviderName "Microsoft-Dynamics-AX-FormServer","Microsoft-Dynamics-AX-XppRuntime" -OutputFormat CSV This will start a new Event Tracing session with the comma separated output format. It uses "Microsoft-Dynamics-AX-FormServer","Microsoft-Dynamics-AX-XppRuntime" as the providernames. It uses the default output folder "C:\Temp\d365fo.tools\EventTrace". It will use the default values for the remaining parameters. .NOTES Tags: ETL, EventTracing, EventTrace Author: Mötz Jensen (@Splaxi) This cmdlet/function was inspired by the work of Michael Stashwick (@D365Stuff) He blog is located here: https://www.d365stuff.co/ 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/ #> function Start-D365EventTrace { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)] [string[]] $ProviderName, [string] $OutputPath = (Join-Path -Path $Script:DefaultTempPath -ChildPath "EventTrace"), [string] $SessionName = "d365fo.tools.trace", [string] $FileName = "d365fo.tools.trace.etl", [ValidateSet('bin', 'bincirc', 'csv', 'sql', 'tsv')] [string] $OutputFormat = "bincirc", [Int32] $MinBuffer = 10240, [Int32] $MaxBuffer = 10240, [Int32] $BufferSizeKB = 1024, [Int32] $MaxLogFileSizeMB = 4096 ) begin { $providers = New-Object System.Collections.Generic.List[string] if (-not (Test-PathExists -Path $OutputPath -Type Container -Create)) { return } Write-PSFMessage -Level Verbose -Message "Configuring the permissions on the folder to make sure the Start-Trace command can read the files." -Target $OutputPath $propagation = [system.security.accesscontrol.PropagationFlags]"None" $inherit = [system.security.accesscontrol.InheritanceFlags]"ContainerInherit, ObjectInherit" $accessRule = New-Object system.security.accesscontrol.filesystemaccessrule("BUILTIN\Users", "FullControl", $inherit, $propagation, "Allow") $aclFolder = Get-Acl -Path $OutputPath $aclFolder.AddAccessRule($accessRule) Set-Acl -Path $OutputPath -AclObject $aclFolder $providerListPath = Join-Path -Path $OutputPath -ChildPath "ProviderList.txt" } process { foreach ($name in $ProviderName) { Write-PSFMessage -Level Verbose -Message "Adding the $name to the list of providers." -Target $name $providers.Add($name) } } end { Write-PSFMessage -Level Verbose -Message "Storing the providers in '$providerListPath' as a UTF8 (NON-BOM) file." -Target $providerListPath $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False [System.IO.File]::WriteAllLines($providerListPath, $($providers.ToArray() -join [System.Environment]::NewLine), $Utf8NoBomEncoding) $outputFile = Join-Path -Path $OutputPath -ChildPath $FileName Write-PSFMessage -Level Verbose -Message "Starting the trace now." Start-Trace -SessionName $SessionName -OutputFilePath $outputFile -ProviderFilePath $providerListPath -ETS -Format $OutputFormat -MinBuffers $MinBuffer -MaxBuffers $MaxBuffer -BufferSizeInKB $BufferSizeKB -MaxLogFileSizeInMB $MaxLogFileSizeMB } } ================================================ FILE: d365fo.tools/functions/stop-d365environment.ps1 ================================================  <# .SYNOPSIS Cmdlet to stop the different services in a Dynamics 365 Finance & Operations environment .DESCRIPTION Can stop all relevant services that is running in a D365FO environment .PARAMETER ComputerName An array of computers that you want to stop services on. .PARAMETER All Set when you want to stop all relevant services Includes: Aos Batch Financial Reporter .PARAMETER Aos Stop the Aos (iis) service .PARAMETER Batch Stop the batch service .PARAMETER FinancialReporter Start the financial reporter (Management Reporter 2012) service .PARAMETER DMF Start the Data Management Framework service .PARAMETER Kill Instructs the cmdlet to kill the service(s) that you want to stop .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .EXAMPLE PS C:\> Stop-D365Environment This will run the cmdlet with the default parameters. Default is "-All". This will stop all D365FO services on the machine. .EXAMPLE PS C:\> Stop-D365Environment -ShowOriginalProgress This will run the cmdlet with the default parameters. Default is "-All". This will Stop all D365FO services on the machine. The progress of Stopping the different services will be written to the console / host. .EXAMPLE PS C:\> Stop-D365Environment -All This will stop all D365FO services on the machine. .EXAMPLE PS C:\> Stop-D365Environment -Aos -Batch This will stop the Aos & Batch D365FO services on the machine. .EXAMPLE PS C:\> Stop-D365Environment -FinancialReporter -DMF This will stop the FinancialReporter and DMF services on the machine. .EXAMPLE PS C:\> Stop-D365Environment -All -Kill This will stop all D365FO services on the machine. It will use the Kill parameter to make sure that the services is stopped. .NOTES Author: Mötz Jensen (@Splaxi) #> function Stop-D365Environment { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueSwitchParameter", "")] [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 1 )] [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 1 )] [string[]] $ComputerName = @($env:computername), [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )] [switch] $All = $true, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 2 )] [switch] $Aos, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 3 )] [switch] $Batch, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 4 )] [switch] $FinancialReporter, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 5 )] [switch] $DMF, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 6 )] [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 6 )] [switch] $Kill, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 7 )] [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 7 )] [switch] $ShowOriginalProgress ) if ($PSCmdlet.ParameterSetName -eq "Specific") { $All = $false } if ((-not ($All)) -and (-not ($Aos)) -and (-not ($Batch)) -and (-not ($FinancialReporter)) -and (-not ($DMF))) { Write-PSFMessage -Level Host -Message "You have to use at least one switch when running this cmdlet. Please run the cmdlet again." Stop-PSFFunction -Message "Stopping because of missing parameters" return } $warningActionValue = "SilentlyContinue" if ($ShowOriginalProgress) { $warningActionValue = "Continue" } $Params = Get-DeepClone $PSBoundParameters if ($Params.ContainsKey("ComputerName")) { $null = $Params.Remove("ComputerName") } if ($Params.ContainsKey("ShowOriginalProgress")) { $null = $Params.Remove("ShowOriginalProgress") } if ($Params.ContainsKey("Kill")) { $null = $Params.Remove("Kill") } $Services = Get-ServiceList @Params $Results = foreach ($server in $ComputerName) { Write-PSFMessage -Level Verbose -Message "Working against: $server - stopping services" if (-not $Kill) { Get-Service -ComputerName $server -Name $Services -ErrorAction SilentlyContinue | Stop-Service -Force -ErrorAction SilentlyContinue -WarningAction $warningActionValue } else { Get-Service -ComputerName $server -Name $Services -ErrorAction SilentlyContinue | ForEach-Object { $service = Get-CimInstance -ClassName "win32_service" -Filter "Name = '$($_.Name)'" Stop-Process -Id "$($service.ProcessId)" -Force -ErrorAction SilentlyContinue -WarningAction $warningActionValue } } } $Results = foreach ($server in $ComputerName) { Write-PSFMessage -Level Verbose -Message "Working against: $server - listing services" Get-Service -ComputerName $server -Name $Services -ErrorAction SilentlyContinue | Select-Object @{Name = "Server"; Expression = { $Server } }, Name, Status, StartType, DisplayName } Write-PSFMessage -Level Verbose "Results are: $Results" -Target ($Results.Name -join ",") $Results | Select-PSFObject -TypeName "D365FO.TOOLS.Environment.Service" Server, DisplayName, Status, StartType, Name } ================================================ FILE: d365fo.tools/functions/stop-d365eventtrace.ps1 ================================================  <# .SYNOPSIS Stop an Event Trace session .DESCRIPTION Stop an Event Trace session that you have started earlier with the d365fo.tools .PARAMETER SessionName Name of the tracing session that you want to stop Default value is "d365fo.tools.trace" .EXAMPLE PS C:\> Stop-D365EventTrace This will stop an Event Trace session. It will use the "d365fo.tools.trace" as the SessionName parameter. .NOTES Tags: ETL, EventTracing, EventTrace Author: Mötz Jensen (@Splaxi) This cmdlet/function was inspired by the work of Michael Stashwick (@D365Stuff) He blog is located here: https://www.d365stuff.co/ 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/ #> function Stop-D365EventTrace { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [string] $SessionName = "d365fo.tools.trace" ) end { Write-PSFMessage -Level Verbose -Message "Stopping the trace" -Target $SessionName Stop-Trace -SessionName $SessionName -ETS } } ================================================ FILE: d365fo.tools/functions/switch-d365activedatabase.ps1 ================================================  <# .SYNOPSIS Switches the 2 databases. The Old wil be renamed _original .DESCRIPTION Switches the 2 databases. The Old wil be renamed _original .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER SourceDatabaseName The database that takes the DatabaseName's place .PARAMETER DestinationSuffix The suffix that you want to append onto the database that is being switched out (DestinationDatabaseName / DatabaseName) The default value is "_original" to mimic the official guides from Microsoft .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Switch-D365ActiveDatabase -SourceDatabaseName "GoldenConfig" This will switch the default database AXDB out and put "GoldenConfig" in its place instead. It will use the default value for DestinationSuffix which is "_original". The destination database "AXDB" will be renamed to "AXDB_original". The GoldenConfig database will be renamed to "AXDB". .EXAMPLE PS C:\> Switch-D365ActiveDatabase -SourceDatabaseName "AXDB_original" -DestinationSuffix "_reverted" This will switch the default database AXDB out and put "AXDB_original" in its place instead. It will use the "_reverted" value for DestinationSuffix parameter. The destination database "AXDB" will be renamed to "AXDB_reverted". The "AXDB_original" database will be renamed to "AXDB". This is used when you did a switch already and need to switch back to the original database. This example assumes that the used the first example to switch in the GoldenConfig database with default parameters. .NOTES Author: Mötz Jensen (@Splaxi) Author: Rasmus Andersen (@ITRasmus) #> function Switch-D365ActiveDatabase { [CmdletBinding()] param ( [string] $DatabaseServer = $Script:DatabaseServer, [Alias('DestinationDatabaseName')] [string] $DatabaseName = $Script:DatabaseName, [string] $SqlUser = $Script:DatabaseUserName, [string] $SqlPwd = $Script:DatabaseUserPassword, [Parameter(Mandatory = $true)] [Alias('NewDatabaseName')] [string] $SourceDatabaseName, [string] $DestinationSuffix = "_original", [switch] $EnableException ) $dbToBeName = "$DatabaseName$DestinationSuffix" $SqlParamsToBe = @{ DatabaseServer = $DatabaseServer; DatabaseName = "master"; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $dbName = Get-D365Database -Name "$dbToBeName" @SqlParamsToBe if (-not($null -eq $dbName)) { $messageString = "There already exists a database named: `"$dbToBeName`" on the server. You need to run the Remove-D365Database cmdlet to remove the already existing database. Re-run this cmdlet once the other database has been removed." Write-PSFMessage -Level Host -Message $messageString -Target $dbToBeName Stop-PSFFunction -Message "Stopping because database already exists on the server." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) return } $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParamsSource = @{ DatabaseServer = $DatabaseServer; DatabaseName = $SourceDatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParamsSource -TrustedConnection $UseTrustedConnection $SqlCommand.CommandText = "SELECT COUNT(1) FROM dbo.USERINFO WHERE ID = 'Admin'" try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) Write-PSFMessage -Level Verbose -Message "Testing the new database for being a valid AXDB database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $null = $sqlCommand.ExecuteScalar() } catch { $messageString = "It seems that the new database either doesn't exists, isn't a valid AxDB database or your don't have enough permissions." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } } $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = "master"; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection if ($DatabaseServer -like "*database.windows.net") { $commandText = (Get-Content "$script:ModuleRoot\internal\sql\switch-database-tier2.sql") -join [Environment]::NewLine } else { $commandText = (Get-Content "$script:ModuleRoot\internal\sql\switch-database-tier1.sql") -join [Environment]::NewLine } $sqlCommand.CommandText = $commandText $null = $sqlCommand.Parameters.AddWithValue("@DestinationName", $DatabaseName) $null = $sqlCommand.Parameters.AddWithValue("@SourceName", $SourceDatabaseName) $null = $sqlCommand.Parameters.AddWithValue("@ToBeName", $dbToBeName) try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) Write-PSFMessage -Level Verbose -Message "Switching out the $DatabaseName database with: $SourceDatabaseName." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $null = $sqlCommand.ExecuteNonQuery() } catch { $messageString = "Something went wrong while switching out the AXDB database." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } [PSCustomObject]@{ OldDatabaseNewName = "$dbToBeName" } } ================================================ FILE: d365fo.tools/functions/test-d365command.ps1 ================================================  <# .SYNOPSIS Validate or show parameter set details with colored output .DESCRIPTION Analyze a function and it's parameters The cmdlet / function is capable of validating a string input with function name and parameters .PARAMETER CommandText The string that you want to analyze If there is parameter value present, you have to use the opposite quote strategy to encapsulate the string correctly E.g. for double quotes -CommandText 'Import-D365Bacpac -ImportModeTier2 -SqlUser "sqladmin" -SqlPwd "XyzXyz" -BacpacFile2 "C:\temp\uat.bacpac"' E.g. for single quotes -CommandText "Import-D365Bacpac -ExportModeTier2 -SqlUser 'sqladmin' -SqlPwd 'XyzXyz' -BacpacFile2 'C:\temp\uat.bacpac'" .PARAMETER Mode The operation mode of the cmdlet / function Valid options are: - Validate - ShowParameters .PARAMETER SplatInput Pass in your hashtable that you use for your command execution and have it validated .PARAMETER ShowSplatStyleV1 Include an hashtable splatting for all parameter sets in the output The example is built like this: PS C:\> $params = @{} PS C:\> $params.PropertyName = "SAMPLEVALUE" PS C:\> Test-FakeCommand @params .PARAMETER ShowSplatStyleV2 Include an hashtable splatting for all parameter sets in the output The example is built like this: PS C:\> $params = @{ PS C:\> PropertyName = "SAMPLEVALUE" PS C:\> } PS C:\> Test-FakeCommand @params .PARAMETER IncludeHelp Switch to instruct the cmdlet / function to output a simple guide with the colors in it .EXAMPLE PS C:\> Test-D365Command -CommandText 'Import-D365Bacpac -ImportModeTier2 -SqlUser "sqladmin" -SqlPwd "XyzXyz" -BacpacFile2 "C:\temp\uat.bacpac"' -Mode "Validate" -IncludeHelp This will validate all the parameters that have been passed to the Import-D365Bacpac cmdlet. All supplied parameters that matches a parameter will be marked with an asterisk. Will print the coloring help. .EXAMPLE PS C:\> Test-D365Command -CommandText 'Import-D365Bacpac' -Mode "ShowParameters" -IncludeHelp This will display all the parameter sets and their individual parameters. Will print the coloring help. .EXAMPLE PS C:\> $params = @{} PS C:\> $params.DatabaseName = "SAMPLEVALUE" PS C:\> Test-D365Command -CommandText 'Import-D365Bacpac -ImportModeTier2' -SplatInput $params -Mode "Validate" This builds a hashtable with a property names "DatabaseName". The hashtable is passed to the cmdlet to be part of the validation. .NOTES Author: Mötz Jensen (@Splaxi) #> function Test-D365Command { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 1)] [string] $CommandText, [Parameter(Mandatory = $true, Position = 2)] [ValidateSet('Validate', 'ShowParameters')] [string] $Mode, [hashtable] $SplatInput, [switch] $ShowSplatStyleV1, [switch] $ShowSplatStyleV2, [switch] $IncludeHelp ) $commonParameters = 'Verbose', 'Debug', 'ErrorAction', 'WarningAction', 'InformationAction', 'ErrorVariable', 'WarningVariable', 'InformationVariable', 'OutVariable', 'OutBuffer', 'PipelineVariable', 'Confirm', 'WhatIf' $colorParmsNotFound = "Red" $colorCommandName = "Green" $colorMandatoryParam = "Yellow" $colorNonMandatoryParam = "DarkGray" $colorFoundAsterisk = "Green" $colorNotFoundAsterisk = "Magenta" $colParmValue = "DarkCyan" $colorEqualSign = "DarkGray" $colorVariable = "Green" $colorProperty = "White" $colorCommandNameSplat = "Yellow" $colorComment = "DarkGreen" if(-not ($null -eq $SplatInput)) { $CommandText = "$CommandText "+ $(($SplatInput.Keys | ForEach-Object {"-$($_) `"$($SplatInput.Item($_))`""}) -Join " " ) } #Match to find the command name: Non-Whitespace until the first whitespace $commandMatch = ($CommandText | Select-String '\S+\s*').Matches if ($null -eq $commandMatch) { Write-PSFMessage -Level Host -Message "The function was unable to extract a valid command name from the supplied command text. Please try again." Stop-PSFFunction -Message "Stopping because of missing command name." return } $commandName = $commandMatch.Value.Trim() $res = Get-Command $commandName -ErrorAction Ignore if ($null -eq $res) { 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." Stop-PSFFunction -Message "Stopping because command name didn't return any help." return } $sbHelp = New-Object System.Text.StringBuilder $sbParmsNotFound = New-Object System.Text.StringBuilder $sbSplatStyleV1 = New-Object System.Text.StringBuilder $sbSplatStyleV2 = New-Object System.Text.StringBuilder switch ($Mode) { "Validate" { #Match to find the parameters: Whitespace Dash Non-Whitespace $inputParameterMatch = ($CommandText | Select-String '\s{1}[-]\S+' -AllMatches).Matches if (-not ($null -eq $inputParameterMatch)) { $inputParameterNames = $inputParameterMatch.Value.Trim("-", " ") Write-PSFMessage -Level Verbose -Message "All input parameters - $($inputParameterNames -join ",")" -Target ($inputParameterNames -join ",") } else { Write-PSFMessage -Level Host -Message "The function was unable to extract any parameters from the supplied command text. Please try again." Stop-PSFFunction -Message "Stopping because of missing input parameters." return } $availableParameterNames = (Get-Command $commandName).Parameters.keys | Where-Object {$commonParameters -NotContains $_} Write-PSFMessage -Level Verbose -Message "Available parameters - $($availableParameterNames -join ",")" -Target ($availableParameterNames -join ",") $inputParameterNotFound = $inputParameterNames | Where-Object {$availableParameterNames -NotContains $_} if ($inputParameterNotFound.Length -gt 0) { $null = $sbParmsNotFound.AppendLine("Parameters that don't exists") $inputParameterNotFound | ForEach-Object { $null = $sbParmsNotFound.AppendLine("$($_)") } } foreach ($parmSet in (Get-Command $commandName).ParameterSets) { $null = $sb = New-Object System.Text.StringBuilder $null = $sb.AppendLine("ParameterSet Name: $($parmSet.Name) - Validated List") $null = $sb.Append("$commandName ") $parmSetParameters = $parmSet.Parameters | Where-Object name -NotIn $commonParameters foreach ($parameter in $parmSetParameters) { $parmFoundInCommandText = $parameter.Name -In $inputParameterNames $color = "$colorNonMandatoryParam" if ($parameter.IsMandatory -eq $true) { $color = "$colorMandatoryParam" } $null = $sb.Append("-$($parameter.Name)") if ($parmFoundInCommandText) { $null = $sb.Append("* ") } elseif ($parameter.IsMandatory -eq $true) { $null = $sb.Append("* ") } else { $null = $sb.Append(" ") } if (-not ($parameter.ParameterType -eq [System.Management.Automation.SwitchParameter])) { $null = $sb.Append("PARAMVALUE ") } } $null = $sb.AppendLine("") Write-PSFHostColor -String "$($sb.ToString())" } $null = $sbHelp.AppendLine("") $null = $sbHelp.AppendLine("$colorParmsNotFound = Parameter not found") $null = $sbHelp.AppendLine("$colorCommandName = Command Name") $null = $sbHelp.AppendLine("$colorMandatoryParam = Mandatory Parameter") $null = $sbHelp.AppendLine("$colorNonMandatoryParam = Optional Parameter") $null = $sbHelp.AppendLine("$colParmValue = Parameter value") $null = $sbHelp.AppendLine("* = Parameter was filled") $null = $sbHelp.AppendLine("* = Mandatory missing") } "ShowParameters" { foreach ($parmSet in (Get-Command $commandName).ParameterSets) { $sb = New-Object System.Text.StringBuilder $sbSplatStyleV1 = New-Object System.Text.StringBuilder $sbSplatStyleV2 = New-Object System.Text.StringBuilder $null = $sb.AppendLine("ParameterSet Name: $($parmSet.Name) - Parameter List") $null = $sb.Append("$commandName ") $null = $sbSplatStyleV1.AppendLine("#Hashtable splatting style V1 - ParameterSet Name: $($parmSet.Name)").AppendLine("`$params = @{}") $null = $sbSplatStyleV2.AppendLine("#Hashtable splatting style V2 - ParameterSet Name: $($parmSet.Name)").AppendLine("`$params = @{") $parmSetParameters = $parmSet.Parameters | Where-Object name -NotIn $commonParameters foreach ($parameter in $parmSetParameters) { $color = "$colorNonMandatoryParam" $mandatoryComment = $null if ($parameter.IsMandatory -eq $true) { $color = "$colorMandatoryParam" $mandatoryComment = " #MANDATORY" } $null = $sbSplatStyleV1.AppendLine("`$params.$($parameter.Name) = `"SAMPLEVALUE`"$mandatoryComment") $null = $sbSplatStyleV2.AppendLine("$($parameter.Name) = `"SAMPLEVALUE`"$mandatoryComment") $null = $sb.Append("-$($parameter.Name) ") if (-not ($parameter.ParameterType -eq [System.Management.Automation.SwitchParameter])) { $null = $sb.Append("PARAMVALUE ") } } $null = $sb.AppendLine("") $null = $sbSplatStyleV2.AppendLine("}") $null = $sbSplatStyleV1.AppendLine("$commandName @params") $null = $sbSplatStyleV2.AppendLine("$commandName @params") Write-PSFHostColor -String "$($sb.ToString())" if ($ShowSplatStyleV1) { Write-PSFHostColor -String "$($sbSplatStyleV1.ToString())" } if ($ShowSplatStyleV2) { Write-PSFHostColor -String "$($sbSplatStyleV2.ToString())" } } $null = $sbHelp.AppendLine("") $null = $sbHelp.AppendLine("$colorCommandName = Command Name") $null = $sbHelp.AppendLine("$colorMandatoryParam = Mandatory Parameter") $null = $sbHelp.AppendLine("$colorNonMandatoryParam = Optional Parameter") $null = $sbHelp.AppendLine("$colParmValue = Parameter value") } Default {} } if ($sbParmsNotFound.ToString().Trim().Length -gt 0) { Write-PSFHostColor -String "$($sbParmsNotFound.ToString())" } if ($IncludeHelp) { Write-PSFHostColor -String "$($sbHelp.ToString())" } } ================================================ FILE: d365fo.tools/functions/test-d365dataverseconnection.ps1 ================================================  <# .SYNOPSIS Test the dataverse connection .DESCRIPTION Invokes the built-in http communication endpount, that validates the connection between the D365FO environment and dataverse .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .EXAMPLE PS C:\> Test-D365DataverseConnection This will invoke the http communication component, that validates the basic settings between D365FO and Dataverse. It will output the raw details from the call, to make it easier to troubleshoot the connectivity between D365FO and Dataverse. .NOTES General notes #> function Test-D365DataverseConnection { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [string] $BinDir = "$Script:BinDir\bin" ) begin { } process { $cdsApiPath = "sdkmessages"; $httpCommunicationDllPath = Join-Path -Path $BinDir -ChildPath "Microsoft.Dynamics.HttpCommunication.dll" if (-not (Test-PathExists -Path $httpCommunicationDllPath -Type Leaf)) { return } Write-PSFMessage -Level Verbose -Message "Loading the 'Microsoft.Dynamics.HttpCommunication.dll' file into the current session." Add-Type -Path $httpCommunicationDllPath try { Write-PSFMessage -Level Verbose -Message "Building the logger object, to handle the output from the test." $assembly = [System.Reflection.Assembly]::LoadFile($httpCommunicationDllPath) $loggerType = $assembly.GetType("Microsoft.Dynamics.HttpCommunication.Logging.InMemoryLogger") $bindingFlags = [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::Public $loggerConstructor = $loggerType.GetConstructor($bindingFlags, $null, [System.Type]::EmptyTypes, $null) $logger = $loggerConstructor.Invoke($null) Write-PSFMessage -Level Verbose -Message "Building the client/request object, to execute the test / validation." $cdsWebApiClient = New-Object Microsoft.Dynamics.HttpCommunication.Cds.CdsWebApiClient $logger; $bindingFlags = [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic $method = [Microsoft.Dynamics.HttpCommunication.Cds.CdsWebApiClient].GetMethod("GetWithStringResponse", $bindingFlags, $null, @([string]), $null) Write-PSFMessage -Level Verbose -Message "Invoking the test / validation request." $task = $method.Invoke($cdsWebApiClient, @($cdsApiPath)) $response = $task.GetAwaiter().GetResult() $response } catch { Write-PSFHostColor -String $logger.LogContent.ToString() -DefaultColor Red if ($logger.LogContent.ToString() -like '*Cannot Find Thumbprint by Certificatename*') { Write-PSFMessage -Level Host -Message "The 'Cannot Find Thumbprint by Certificatename' indicates that you need to run the 'New-D365EntraIntegration' cmdlet." Write-PSFMessage -Level Host -Message "You should read the following links: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-tools/secure-developer-vm#external-integrations and https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/business-events/che-be-ve-error." Stop-PSFFunction -Message "Stopping because the 'Cannot Find Thumbprint by Certificatename' error was encounted" return } elseif ($logger.LogContent.ToString() -like '*Expected aud https://securityservice.operations365.dynamics.com*') { Write-PSFMessage -Level Host -Message "The 'Expected aud https://securityservice.operations365.dynamics.com' indicates that you need to configure Azure Entra (Registered Application) between your D365FO environment and the connected Dataverse environment." Write-PSFMessage -Level Host -Message "You should read the following link: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/business-events/che-be-ve-error." Stop-PSFFunction -Message "Stopping because the 'Cannot Find Thumbprint by Certificatename' error was encounted" return } } } end { } } ================================================ FILE: d365fo.tools/functions/test-d365entraintegration.ps1 ================================================  <# .SYNOPSIS Test the Entra Id integration .DESCRIPTION Validates the configuration of the web.config file and the certificate for the environment If any of the configuration is missing or in someway incorrect, it will prompt and stating corrective actions needed .EXAMPLE PS C:\> Test-D365EntraIntegration This will validate the settings inside the web.config file. It will search for Aad.Realm, Infrastructure.S2SCertThumbprint, GraphApi.GraphAPIServicePrincipalCert It will search for the certificate that matches the thumbprint. A result set example: EntraAppId Thumbprint Subject Expiration ---------- ---------- ------- ---------- e068e004-8bec-48c3-a36f-2ab4982ee738 0768175DF3DFDEA3FA78925ADC1E588707649335 CN=CHEAuth 2/5/2026 8:09:28 AM .NOTES Based on: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-tools/secure-developer-vm#external-integrations Author: Mötz Jensen (@Splaxi) #> function Test-D365EntraIntegration { param ( ) if (-not ($Script:IsAdminRuntime)) { Write-PSFMessage -Level Critical -Message "It seems that you ran this cmdlet non-elevated. 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`"" Stop-PSFFunction -Message "Stopping because the function is not run elevated" return } # Check web.config $webConfigFile = Join-Path -Path $Script:AOSPath $Script:WebConfig if (-not (Test-PathExists -Path $webConfigFile -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue)) { Write-PSFMessage -Level Host -Message "Unable to find the web.config file." Stop-PSFFunction -Message "Stopping because the web.config file could not be found" } $config = @{} [xml]$xml = Get-Content $webConfigFile $nodes = ($xml.configuration.appSettings).ChildNodes $config.AadRealm = $nodes | Where-Object -Property Key -eq "Aad.Realm" | Select-Object -First 1 -ExpandProperty value $config.S2SCertThumbprint = $nodes | Where-Object -Property Key -eq "Infrastructure.S2SCertThumbprint" | Select-Object -First 1 -ExpandProperty value $config.GraphAPIServicePrincipalCert = $nodes | Where-Object -Property Key -eq "GraphApi.GraphAPIServicePrincipalCert" | Select-Object -First 1 -ExpandProperty value if ([System.String]::IsNullOrWhiteSpace($config.AadRealm)) { Write-PSFMessage -Level Host -Message "The 'Aad.Realm' value is empty. This indicates that you need to run the 'New-D365EntraIntegration' cmdlet." Stop-PSFFunction -Message "Stopping because the 'Aad.Realm' value is empty" } if ([System.String]::IsNullOrWhiteSpace($config.S2SCertThumbprint)) { Write-PSFMessage -Level Host -Message "The 'Infrastructure.S2SCertThumbprint' value is empty. This indicates that you need to run the 'New-D365EntraIntegration' cmdlet." Stop-PSFFunction -Message "Stopping because the 'Infrastructure.S2SCertThumbprint' value is empty" } if ([System.String]::IsNullOrWhiteSpace($config.GraphAPIServicePrincipalCert)) { Write-PSFMessage -Level Host -Message "The 'GraphApi.GraphAPIServicePrincipalCert' value is empty. This indicates that you need to run the 'New-D365EntraIntegration' cmdlet." Stop-PSFFunction -Message "Stopping because the 'GraphApi.GraphAPIServicePrincipalCert' value is empty" } if ((-not [System.String]::IsNullOrWhiteSpace($config.S2SCertThumbprint)) -and $config.S2SCertThumbprint -ne $config.GraphAPIServicePrincipalCert) { Write-PSFMessage -Level Host -Message "The 'Infrastructure.S2SCertThumbprint' and the 'GraphApi.GraphAPIServicePrincipalCert' value do not match each other. This indicates that you have a corrupted configuration. Running the 'New-D365EntraIntegration' cmdlet could assist with fixing the configuration." Stop-PSFFunction -Message "Stopping because the 'Infrastructure.S2SCertThumbprint' and 'GraphApi.GraphAPIServicePrincipalCert' values do not match" } if (Test-PSFFunctionInterrupt) { return } # Check wif.config $wifConfigFile = Join-Path -Path $Script:AOSPath $Script:WifConfig if (-not (Test-PathExists -Path $wifConfigFile -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue)) { Write-PSFMessage -Level Host -Message "Unable to find the wif.config file." Stop-PSFFunction -Message "Stopping because the wif.config file could not be found" } [xml]$xml = Get-Content $wifConfigFile $nodes = ($xml.'system.identityModel'.identityConfiguration.securityTokenHandlers.securityTokenHandlerConfiguration.audienceUris).ChildNodes $config.AudienceUri = $nodes | Where-Object { $_.value -like "*$($config.AadRealm)*" } | Select-Object -First 1 -ExpandProperty value if ([System.String]::IsNullOrWhiteSpace($config.AudienceUri)) { Write-PSFMessage -Level Host -Message "The 'AudienceUri' value is empty. This indicates that you have a corrupted configuration. Try running the 'New-D365EntraIntegration' cmdlet to fix the configuration." Stop-PSFFunction -Message "Stopping because the 'AudienceUri' value is empty" } elseif ($config.AadRealm -ne $config.AudienceUri) { Write-PSFMessage -Level Host -Message "The 'Aad.Realm' and the 'AudienceUri' value do not match each other. This indicates that you have a corrupted configuration. Try running the 'New-D365EntraIntegration' cmdlet to fix the configuration." Stop-PSFFunction -Message "Stopping because the 'Aad.Realm' and 'AudienceUri' values do not match" } if (Test-PSFFunctionInterrupt) { return } # Check certificate $certStoreLocation = "Cert:\LocalMachine\My" $certEntra = Get-ChildItem -Path $certStoreLocation -ErrorAction SilentlyContinue | Where-Object { $_.Thumbprint -eq $config.S2SCertThumbprint } | Select-Object -First 1 if ($null -eq $certEntra) { Write-PSFMessage -Level Host -Message "Unable to find any certificate in the certificate store '$certStoreLocation' that matches the thumbprint '$($config.S2SCertThumbprint)'." Stop-PSFFunction -Message "Stopping because no certificate matching the thumbprint was found" return } [PSCustomObject][ordered]@{ EntraAppId = $config.AadRealm.replace("spn:", "") Thumbprint = $config.S2SCertThumbprint Subject = $certEntra.Subject Expiration = $certEntra.NotAfter } } ================================================ FILE: d365fo.tools/functions/test-d365flightservicecatalogid.ps1 ================================================  <# .SYNOPSIS Test if the FlightingServiceCatalogID is present and filled out .DESCRIPTION Test if the FlightingServiceCatalogID element exists in the web.config file used by D365FO .PARAMETER AosServiceWebRootPath Path to the root folder where to locate the web.config file .EXAMPLE PS C:\> Test-D365FlightServiceCatalogId This will open the web.config and check if the FlightingServiceCatalogID element is present or not. .NOTES Tags: Flight, Flighting Author: Mötz Jensen (@Splaxi)) The DataAccess.FlightingServiceCatalogID must already be set in the web.config file. 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 #> function Test-D365FlightServiceCatalogId { [CmdletBinding()] param ( [string]$AosServiceWebRootPath = $Script:AOSPath ) $res = @{} try { $WebConfigFile = Join-Path -Path $AosServiceWebRootPath -ChildPath $Script:WebConfig Write-PSFMessage -Level Verbose -Message "Retrieve the FlightingServiceCatalogID" -Target $WebConfigFile $FlightServiceNode = Select-Xml -XPath "/configuration/appSettings/add[@key='DataAccess.FlightingServiceCatalogID']/@value" -Path $WebConfigFile if($null -eq $FlightServiceNode){ Write-PSFMessage -Level Host -Message "The DataAccess.FlightingServiceCatalogID child element under the AppSettings element is missing. 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." Stop-PSFFunction -Message "Stopping because of errors" return } $res.FlightingServiceCatalogID = $FlightServiceNode.Node.Value Write-PSFMessage -Level Verbose -Message "FlightingServiceCatalogID: $FlightServiceId" -Target $WebConfigFile } catch { Write-PSFMessage -Level Host -Message "Something went wrong while reading from the web.config file" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } if(-not [System.String]::IsNullOrEmpty($res.FlightingServiceCatalogID)){ [PsCustomObject]$res } } ================================================ FILE: d365fo.tools/functions/test-d365labelidisvalid.ps1 ================================================  <# .SYNOPSIS Checks if a string is a valid 'Label Id' format .DESCRIPTION This function will validate if a string is a valid 'Label Id' format. .PARAMETER LabelId The LabelId string thay you want to validate .EXAMPLE PS C:> Test-D365LabelIdIsValid -LabelId "ABC123" This will test the if the LabelId is valid. It will use the "ABC123" as the LabelId parameter. The expected result is $true .EXAMPLE PS C:> Test-D365LabelIdIsValid -LabelId "@ABC123" This will test the if the LabelId is valid. It will use the "@ABC123" as the LabelId parameter. The expected result is $true .EXAMPLE PS C:> Test-D365LabelIdIsValid -LabelId "@ABC123_1" This will test the if the LabelId is valid. It will use the "@ABC123_1" as the LabelId parameter. The expected result is $false .EXAMPLE PS C:> Test-D365LabelIdIsValid -LabelId "ABC.123" #False This will test the if the LabelId is valid. It will use the "ABC.123" as the LabelId parameter. The expected result is $false .NOTES Author: Alex Kwitny (@AlexOnDAX) The intent of this function is to be used with other methods to create valid labels via scripting. #> function Test-D365LabelIdIsValid { [CmdletBinding()] [OutputType([bool])] param ( [Parameter(Mandatory = $True)] [string] $LabelId ) $RegexOptions = [System.Text.RegularExpressions.RegexOptions]::IgnoreCase -bor [System.Text.RegularExpressions.RegexOptions]::Compiled -bor [System.Text.RegularExpressions.RegexOptions]::CultureInvariant $Matcher_New_LabelID = New-Object System.Text.RegularExpressions.Regex('(^[a-zA-Z_])([a-zA-Z\d_])*$', $RegexOptions) $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) $Matcher_New_Label_WithLabelFile = New-Object System.Text.RegularExpressions.Regex("(?\@)(?[a-zA-Z]\w*):(?[a-zA-Z]\w*)", $RegexOptions) if (!$LabelId) { $false return } if (!($Matcher_New_LabelID.IsMatch($LabelId)) -and !($Matcher_Legacy_LabelID.IsMatch($LabelId))) { $Matcher_New_Label_WithLabelFile.IsMatch($LabelId) return } $true } ================================================ FILE: d365fo.tools/functions/update-d365bacpacmodelfilesingletable.ps1 ================================================  <# .SYNOPSIS Update the "model.xml" from the bacpac file to a single table .DESCRIPTION Update the "model.xml" file from inside the bacpac file to only handle a single table This can be used to restore a single table as fast as possible to a new data 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 The output can be used directly with the Import-D365Bacpac cmdlet and its ModelFile parameter, see the example sections for more details .PARAMETER Path Path to the bacpac file that you want to work against It can also be a zip file .PARAMETER Table Name of the table that you want to be kept inside the model file when the update is done .PARAMETER Schema Schema where the table that you want to work against exists The default value is "dbo" .PARAMETER OutputPath Path to where you want the updated bacpac model file to be saved Default value is: "c:\temp\d365fo.tools" .PARAMETER Force Switch to instruct the cmdlet to overwrite the bacpac model file specified in the OutputPath .EXAMPLE PS C:\> Update-D365BacpacModelFileSingleTable -Path "c:\temp\d365fo.tools\bacpac.model.xml" -Table "SalesTable" This will create an updated bacpac.model.xml file with only the SalesTable to be imported. It will read the "c:\temp\d365fo.tools\bacpac.model.xml" file. It will use the default "dbo" as the Schema parameter. It will use the "SalesTable" as the Table parameter. It will use the "c:\temp\d365fo.tools\dbo.salestable.model.xml" as the default path for OutputPath parameter. .EXAMPLE PS C:\> Update-D365BacpacModelFileSingleTable -Path "c:\temp\d365fo.tools\bacpac.model.xml" -Table "CommissionSalesGroup" -Schema "AX" This will create an updated bacpac.model.xml file with only the "CommissionSalesGroup", from the "AX" schema, to be imported. It will read the "c:\temp\d365fo.tools\bacpac.model.xml" file. It will use the "AX" as the Schema for the table. It will use the "CommissionSalesGroup" as the Table parameter. It will use the "c:\temp\d365fo.tools\ax.CommissionSalesGroup.model.xml" as the default path for OutputPath parameter. .EXAMPLE PS C:\> Update-D365BacpacModelFileSingleTable -Path "c:\temp\d365fo.tools\bacpac.model.xml" -Table "SalesTable" -OutputPath "c:\temp\troubleshoot.xml" This will create an updated bacpac.model.xml file with only the SalesTable to be imported. It will read the "c:\temp\d365fo.tools\bacpac.model.xml" file. It will use the default "dbo" as the Schema parameter. It will use the "SalesTable" as the Table parameter. It will use the "c:\temp\troubleshoot.xml" as the path for OutputPath parameter. .EXAMPLE PS C:\> Export-D365BacpacModelFile -Path "c:\Temp\AxDB.bacpac" | Update-D365BacpacModelFileSingleTable -Table SalesTable This will create an updated bacpac.model.xml file with only the SalesTable to be imported. It will read the bacpac model file generated from the Export-D365BacpacModelFile cmdlet. It will use the default "dbo" as the Schema parameter. It will use the "SalesTable" as the Table parameter. It will use the "c:\temp\d365fo.tools\dbo.salestable.model.xml" as the default path for OutputPath parameter. .EXAMPLE PS C:\> Update-D365BacpacModelFileSingleTable -Path "c:\temp\d365fo.tools\bacpac.model.xml" -Table "SalesTable" -Force This will create an updated bacpac.model.xml file with only the SalesTable to be imported. It will read the "c:\temp\d365fo.tools\bacpac.model.xml" file. It will use the default "dbo" as the Schema parameter. It will use the "SalesTable" as the Table parameter. It will use the "c:\temp\d365fo.tools\dbo.salestable.model.xml" as the default path for OutputPath parameter. It will overwrite the "c:\temp\d365fo.tools\dbo.salestable.model.xml" if it already exists. .NOTES Tags: Bacpac, Servicing, Data, SqlPackage, Import, Table, Troubleshooting Author: Mötz Jensen (@Splaxi) #> function Update-D365BacpacModelFileSingleTable { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('ModelFile')] [Alias('File')] [string] $Path, [Parameter(Mandatory = $true)] [string] $Table, [string] $Schema = "dbo", [string] $OutputPath = $Script:DefaultTempPath, [switch] $Force ) begin { Invoke-TimeSignal -Start if ([System.IO.File]::GetAttributes($OutputPath).HasFlag([System.IO.FileAttributes]::Directory)) { $OutputPath = Join-Path -Path $OutputPath -ChildPath "$Schema.$Table.model.xml" } if (-not $Force) { if ((-not (Test-PathExists -Path $OutputPath -Type Leaf -ShouldNotExist -ErrorAction SilentlyContinue -WarningAction SilentlyContinue))) { Write-PSFMessage -Level Host -Message "The $OutputPath already exists. Consider changing the OutputPath path or set the Force parameter to overwrite the file." return } } if (Test-PSFFunctionInterrupt) { return } if ($Schema -NotLike "[*]") { $Schema = "[$Schema]" } if ($Table -NotLike "[*]") { $Table = "[$Table]" } } process { if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } $xmlFile = [System.Xml.XmlReader]::Create($Path) $settings = [System.Xml.XmlWriterSettings]::new() $settings.Indent = $true $settings.Encoding = [System.Text.UTF8Encoding]::new($false) $outFile = [System.Xml.XmlWriter]::Create($OutputPath, $settings) while ($xmlFile.Read()) { if ($xmlFile.NodeType -in "XmlDeclaration", "ProcessingInstruction") { $outFile.WriteProcessingInstruction($xmlFile.Name, $xmlFile.Value) } elseif ($xmlFile.NodeType -eq "Element" -and $xmlFile.Name -eq "DataSchemaModel") { $outFile.WriteStartElement($xmlFile.name, "http://schemas.microsoft.com/sqlserver/dac/Serialization/2012/02") if ($xmlFile.HasAttributes) { while ($xmlFile.MoveToNextAttribute()) { if ($xmlFile.name -ne "xmlns") { $outFile.WriteAttributeString($xmlFile.Name, $xmlFile.Value) } } } } elseif ($xmlFile.NodeType -eq "Element" -and $xmlFile.Name -eq "Model") { $outFile.WriteStartElement($xmlFile.name) } elseif ($xmlFile.NodeType -eq "Element" -and $xmlFile.Depth -eq 2) { $rawElement = $($xmlFile.ReadOuterXml() -replace 'xmlns=".*"', '') if (-not $($rawElement -match 'Type="(?.*?)".*?>')) { continue } if ($Matches.Type -NotIn "SqlSchema", "SqlTable", "SqlDatabaseOptions", "SqlGenericDatabaseScopedConfigurationOptions", "SqlIndex", "SqlPrimaryKeyConstraint") { continue } if ($Matches.Type -eq "SqlSchema") { if (-not $($rawElement -match 'Name="(?.*?)".*?>')) { continue } if ($Matches.Name -ne $Schema) { continue } Write-PSFMessage -Level Verbose -Message "SqlSchema found" -Target $rawElement } if ($Matches.Type -eq "SqlTable") { if (-not $($rawElement -match 'Name="(?.*?)".*?>')) { continue } if ($Matches.Name -ne "$Schema.$Table") { continue } Write-PSFMessage -Level Verbose -Message "SqlTable found" -Target $rawElement $rawElement = $rawElement -replace "\s*.*", "" } if ($Matches.Type -eq "SqlIndex") { if (-not $($rawElement -match 'Name="(?.*?)".*?>')) { continue } if (-not $Matches.Name.StartsWith("$Schema.$Table", [System.StringComparison]::InvariantCultureIgnoreCase)) { continue } Write-PSFMessage -Level Verbose -Message "SqlIndex found" -Target $rawElement } if ($Matches.Type -eq "SqlPrimaryKeyConstraint") { if (-not $(([System.Xml.XmlDocument]$rawElement).SelectSingleNode("//Relationship[@Name='DefiningTable']/Entry/References/@Name")."#text").Equals("$Schema.$Table", [System.StringComparison]::InvariantCultureIgnoreCase)) { continue } Write-PSFMessage -Level Verbose -Message "SqlPrimaryKeyConstraint found" -Target $rawElement } $outFile.WriteRaw($rawElement) } else { if ($xmlFile.NodeType -eq "EndElement" -and $xmlFile.Name -in "Model", "DataSchemaModel") { $outFile.WriteEndElement() } } } [PSCustomObject]@{ File = $OutputPath Filename = $(Split-Path -Path $OutputPath -Leaf) } } end { if ($outFile) { $outFile.Flush() $outFile.Close() $outFile.Dispose() } if ($xmlFile) { $xmlFile.Close() $xmlFile.Dispose() } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/functions/update-d365user.ps1 ================================================  <# .SYNOPSIS Updates the user details in the database .DESCRIPTION Is capable of updating all the user details inside the UserInfo table to enable a user to sign in .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER Email The search string to select which user(s) should be updated. The parameter supports wildcards. E.g. -Email "*@contoso.com*" .PARAMETER Company The company the user should start in. .EXAMPLE PS C:\> Update-D365User -Email "claire@contoso.com" 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 .EXAMPLE PS C:\> Update-D365User -Email "*contoso.com" 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 .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Update-D365User { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [string]$DatabaseServer = $Script:DatabaseServer, [string]$DatabaseName = $Script:DatabaseName, [string]$SqlUser = $Script:DatabaseUserName, [string]$SqlPwd = $Script:DatabaseUserPassword, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string]$Email, [string]$Company ) begin { Invoke-TimeSignal -Start $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters $SqlParams = @{ DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd } $SqlCommand = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection $sqlCommand_Update = Get-SqlCommand @SqlParams -TrustedConnection $UseTrustedConnection try { $sqlCommand.Connection.Open() $sqlCommand_Update.Connection.Open() } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } process { $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\get-user.sql") -join [Environment]::NewLine $null = $sqlCommand.Parameters.Add("@Email", $Email.Replace("*", "%")) $sqlCommand_Update.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\update-user.sql") -join [Environment]::NewLine try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $reader = $sqlCommand.ExecuteReader() while ($reader.Read() -eq $true) { Write-PSFMessage -Level Verbose -Message "Building the update statement with the needed details." $userId = "$($reader.GetString($($reader.GetOrdinal("ID"))))" $networkAlias = "$($reader.GetString($($reader.GetOrdinal("NETWORKALIAS"))))" $userAuth = Get-D365UserAuthenticationDetail $networkAlias $null = $sqlCommand_Update.Parameters.AddWithValue("@id", $userId) $null = $sqlCommand_Update.Parameters.AddWithValue("@networkDomain", $userAuth["NetworkDomain"]) $null = $sqlCommand_Update.Parameters.AddWithValue("@sid", $userAuth["SID"]) $null = $sqlCommand_Update.Parameters.AddWithValue("@identityProvider", $userAuth["IdentityProvider"]) $null = $sqlCommand_Update.Parameters.AddWithValue("@Company", $Company) Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $sqlCommand_Update) $null = $sqlCommand_Update.ExecuteNonQuery() $sqlCommand_Update.Parameters.Clear() } } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { $reader.close() $sqlCommand.Parameters.Clear() } } end { if ($sqlCommand_Update.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand_Update.Connection.Close() } $sqlCommand_Update.Dispose() if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/configurations/configuration.ps1 ================================================ <# This is an example configuration file By default, it is enough to have a single one of them, however if you have enough configuration settings to justify having multiple copies of it, feel totally free to split them into multiple files. #> <# # Example Configuration Set-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'" #> Set-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." Set-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." Set-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." Set-PSFConfig -FullName "d365fo.tools.azure.storage.accounts" -Value @{} -Initialize -Description "Object that stores different Azure Storage Account and their details." Set-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." Set-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." Set-PSFConfig -FullName "d365fo.tools.lcs.projectid" -Value "" -Initialize -Description "Project number for the specific LCS project that you want to upload to." Set-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." Set-PSFConfig -FullName "d365fo.tools.lcs.lcsapiuri" -Value "" -Initialize -Description "URI / URL for the LCS API." Set-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)." Set-PSFConfig -FullName "d365fo.tools.lcs.bearertoken" -Value "" -Initialize -Description "The bearer token used to authenticate / authorize against LCS when you want to upload files." Set-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." Set-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." Set-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." Set-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" Set-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." Set-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." Set-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." Set-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." ================================================ FILE: d365fo.tools/internal/configurations/readme.md ================================================ # Configurations Through the `PSFramework` you have a simple method that allows you to ... - Publish settings - With onboard documentation - Input validation - Scripts that run on change of settings - That can be discovered and updated by the user - That can be administrated by policy & DSC The 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. An example can be seen in the attached ps1 file ================================================ FILE: d365fo.tools/internal/functions/add-aadusersecurity.ps1 ================================================  <# .SYNOPSIS Assign D365 Security configuration .DESCRIPTION Assign the same security configuration as the ADMIN user in the D365FO database .PARAMETER sqlCommand The SQL Command object that should be used when assigning the permissions .PARAMETER Id Id of the user inside the D365FO database .EXAMPLE PS C:\> $SqlParams = @{ DatabaseServer = "localhost" DatabaseName = "AXDB" SqlUser = "sqladmin" SqlPwd = "Pass@word1" TrustedConnection = $false } PS C:\> $SqlCommand = Get-SqlCommand @SqlParams PS C:\> Add-AadUserSecurity -SqlCommand $SqlCommand -Id "TestUser" This will create a new Sql Command object using the Get-SqlCommand cmdlet and the $SqlParams hashtable containing all the needed parameters. 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. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Add-AadUserSecurity { [OutputType('System.Boolean')] param ( [Parameter(Mandatory = $true)] [System.Data.SqlClient.SqlCommand] $SqlCommand, [Parameter(Mandatory = $true)] [string] $Id ) $commandText = (Get-Content "$script:ModuleRoot\internal\sql\Set-AadUserSecurityInD365FO.sql") -join [Environment]::NewLine $sqlCommand.CommandText = $commandText $null = $sqlCommand.Parameters.Add("@Id", $Id) Write-PSFMessage -Level Verbose -Message "Setting security roles in D365FO database" Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $differenceBetweenNewUserAndAdmin = $sqlCommand.ExecuteScalar() Write-PSFMessage -Level Verbose -Message "Difference between new user and admin security roles $differenceBetweenNewUserAndAdmin" -Target $differenceBetweenNewUserAndAdmin $SqlCommand.Parameters.Clear() $differenceBetweenNewUserAndAdmin -eq 0 } ================================================ FILE: d365fo.tools/internal/functions/add-filetopackage.ps1 ================================================  <# .SYNOPSIS Add a file to an archive (zipped) file .DESCRIPTION Add the specified file to the specified archive (zipped) file in the specified path. .PARAMETER File Path to the file that you want to add to the archive .PARAMETER Archive Path to the archive (zipped) file where the file should be added .PARAMETER Path Path where the file should be added to the archive. Default is the root of the archive. .PARAMETER OutputPath Path where you want the modified archive to be stored. Default is the same path as the archive. .PARAMETER ClearPath If the path already exists in the archive, it will be cleared before adding the file. Default is false. .EXAMPLE PS C:\> Add-FileToPackage -File C:\Temp\MyFile.txt -Archive C:\Temp\MyPackage.zip -Path "AOSService\Scripts" This will take the "C:\Temp\MyFile.txt" file and add it to the C:\Temp\MyPackage.zip archive in the "AOSService\Scripts" folder. It will extract the "C:\Temp\MyPackage.zip" and add the "C:\Temp\MyFile.txt" in the "AOSService\Scripts" folder of the extracted archive. It will then compress (zip) the folder created by the extraction back into an archive file, overwriting the previous archive file. .NOTES Author: Mötz Jensen (@splaxi) Author: Szabolcs Eötvös Author: Florian Hopfner (@FH-Inway) #> function Add-FileToPackage { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 1 )] [string] $File, [Parameter(Mandatory = $true, ParameterSetName = 'Default', Position = 2 )] [string] $Archive, [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 3 )] [string] $Path = "", [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 4 )] [string] $OutputPath = $Archive, [Parameter(Mandatory = $false, ParameterSetName = 'Default')] [Switch] $ClearPath ) begin { } process { if (-not (Test-PathExists -Path $File, $Archive -Type "Leaf")) { return } $null = New-Item -Path (Split-Path $OutputPath -Parent) -ItemType Directory -ErrorAction SilentlyContinue Unblock-File $File Unblock-File $Archive $ExtractionPath = [System.IO.Path]::GetTempPath() $packageTemp = Join-Path $ExtractionPath ((Get-Random -Maximum 99999).ToString()) Write-PSFMessage -Level Verbose -Message "Extracting the archive zip file to $packageTemp." -Target $packageTemp Expand-Archive -Path $Archive -DestinationPath $packageTemp $mergePath = Join-Path $packageTemp $Path if (Test-Path -Path $mergePath) { if ($ClearPath) { Get-ChildItem -Path $mergePath | Remove-Item -Force -ErrorAction SilentlyContinue } } else { $null = New-Item -Path $mergePath -ItemType Directory -ErrorAction SilentlyContinue } Write-PSFMessage -Level Verbose -Message "Copying the file into place." Copy-Item -Path $File -Destination $mergePath Write-PSFMessage -Level Verbose -Message "Compressing the folder into a zip file and storing it at $OutputPath" -Target $OutputPath Compress-Archive -Path "$packageTemp\*" -DestinationPath $OutputPath -Force [PSCustomObject]@{ File = $OutputPath } } end { } } ================================================ FILE: d365fo.tools/internal/functions/backup-file.ps1 ================================================  <# .SYNOPSIS Backup a file .DESCRIPTION Backup a file either in the same directory as the original file with a suffix or in a different directory. .PARAMETER File Path to the file that you want to backup .PARAMETER Suffix The suffix value that you want to append to the file name when backing it up in the same directory. .PARAMETER DestinationPath 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. .PARAMETER Force Instructs the cmdlet to overwrite an already existing backup of the file. .EXAMPLE PS C:\> Backup-File -File c:\temp\d365fo.tools\test.txt -Suffix "Original" This will backup the "test.txt" file as "test_Original.txt" inside "c:\temp\d365fo.tools\" .EXAMPLE PS C:\> Backup-File -File c:\temp\d365fo.tools\test.txt -Suffix "Original" -Force This will backup the "test.txt" file as "test_Original.txt" inside "c:\temp\d365fo.tools\" If the file already exists in the destination folder, it will be overwritten. .EXAMPLE PS C:\> Backup-File -File c:\temp\d365fo.tools\test.txt -DestinationPath c:\temp\d365fo.tools\backup This will backup the "test.txt" file to "c:\temp\d365fo.tools\backup\test.txt" .EXAMPLE PS C:\> Backup-File -File c:\temp\d365fo.tools\test.txt -DestinationPath c:\temp\d365fo.tools\backup -Force This will backup the "test.txt" file to "c:\temp\d365fo.tools\backup\test.txt" If the file already exists in the destination folder, it will be overwritten. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) Author: Florian Hopfner (@FH-Inway) #> function Backup-File { [CmdletBinding( DefaultParameterSetName = "SameFolderWithSuffix")] param ( [Parameter(Mandatory = $true)] [string] $File, [Parameter(Mandatory = $true, ParameterSetName = "SameFolderWithSuffix")] [string] $Suffix, [Parameter(Mandatory = $true, ParameterSetName = "DifferentFolder")] [string] $DestinationPath, [switch] $Force ) begin { if (-not (Test-PathExists -Path $File -Type Leaf)) { return } } process { if ($PSCmdlet.ParameterSetName -eq "SameFolderWithSuffix") { $FileBackup = Get-BackupName -File $File -Suffix $Suffix } elseif ($PSCmdlet.ParameterSetName -eq "DifferentFolder") { $FileName = Split-Path -Path $File -Leaf $FileBackup = Join-Path -Path $DestinationPath -ChildPath $FileName } Write-PSFMessage -Level Verbose -Message "Backing up $File to $FileBackup" -Target (@($File, $FileBackup)) if (-not $Force) { if (Test-PathExists -Path $FileBackup -Type Leaf -ErrorAction SilentlyContinue -WarningAction SilentlyContinue) { Write-PSFMessage -Level Host -Message "The $FileBackup already exists. Consider changing the destination path or set the Force parameter to overwrite the file." return } } Copy-Item -Path $File -Destination $FileBackup -Force:$Force -PassThru | Select-PSFObject "Name as Filename", "LastWriteTime as LastModified", "Fullname as File" } } ================================================ FILE: d365fo.tools/internal/functions/complete-lcsuploadv2.ps1 ================================================  <# .SYNOPSIS Complete the upload action in LCS .DESCRIPTION Signal to LCS that the upload of the blob has completed .PARAMETER Token The token to be used for the http request against the LCS API .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER AssetId The unique id of the asset / file that you are trying to upload to LCS .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Complete-LcsUploadV2 -Token "Bearer JldjfafLJdfjlfsalfd..." -ProjectId 123456789 -AssetId "958ae597-f089-4811-abbd-c1190917eaae" -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will commit the upload process for the AssetId "958ae597-f089-4811-abbd-c1190917eaae" in the LCS project with Id 123456789. The http request will be using the "Bearer JldjfafLJdfjlfsalfd..." token for authentication against the LCS API. The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token Author: Mötz Jensen (@Splaxi) #> function Complete-LcsUploadV2 { [CmdletBinding()] [OutputType()] param( [Parameter(Mandatory = $true)] [string]$Token, [Parameter(Mandatory = $true)] [int]$ProjectId, [Parameter(Mandatory = $true)] [string]$AssetId, [Parameter(Mandatory = $false)] [string]$LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "POST" $parms.Uri = "$LcsApiUri/box/fileasset/CommitFileAsset/$($ProjectId)?assetId=$AssetId" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in starting a new database refresh in LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception -Target $_ Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/convert-hashtoargstringswitch.ps1 ================================================  <# .SYNOPSIS Convert HashTable into an array .DESCRIPTION Convert HashTable with switches inside into an array of Key:Value .PARAMETER InputObject The HashTable object that you want to work against Shold only contain Key / Vaule, where value is $true or $false .PARAMETER KeyPrefix The prefix that you want to append to the key of the HashTable The default value is "-" .PARAMETER ValuePrefix The prefix that you want to append to the value of the HashTable The default value is ":" .PARAMETER KeepCase Instruct the cmdlet to keep the naming case of the properties from the hashtable Default value is: $true .EXAMPLE PS C:\> $params = @{NoPrompt = $true; CreateParents = $false} PS C:\> $arguments = Convert-HashToArgStringSwitch -Inputs $params This will convert the $params into an array of strings, each with the "-Key:Value" pattern. .EXAMPLE PS C:\> $params = @{NoPrompt = $true; CreateParents = $false} PS C:\> $arguments = Convert-HashToArgStringSwitch -InputObject $params -KeyPrefix "&" -ValuePrefix "=" This will convert the $params into an array of strings, each with the "&Key=Value" pattern. .NOTES Tags: HashTable, Arguments Author: Mötz Jensen (@Splaxi) #> function Convert-HashToArgStringSwitch { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueSwitchParameter", "")] [CmdletBinding()] [OutputType([System.String])] param ( [HashTable] $InputObject, [string] $KeyPrefix = "-", [string] $ValuePrefix = ":", [switch] $KeepCase = $true ) foreach ($key in $InputObject.Keys) { $value = "{0}" -f $InputObject.Item($key).ToString() if (-not $KeepCase) {$value = $value.ToLower()} "$KeyPrefix$($key)$ValuePrefix$($value)" } } ================================================ FILE: d365fo.tools/internal/functions/convertto-booleanordefault.ps1 ================================================  <# .SYNOPSIS Convert an object to boolean .DESCRIPTION Convert an object to boolean or default it to the specified boolean value .PARAMETER Object Input object that you want to work against .PARAMETER Default The default boolean value you want returned if the convert / cast fails .EXAMPLE PS C:\> ConvertTo-BooleanOrDefault -Object "1" -Default $true This will try and convert the "1" value to a boolean value. If the convert would fail, it would return the default value $true. .NOTES Author: Mötz Jensen (@Splaxi) #> function ConvertTo-BooleanOrDefault { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingEmptyCatchBlock', '')] [CmdletBinding()] [OutputType('System.Boolean')] param ( [Object] $Object, [Boolean] $Default ) [boolean] $result = $Default; $stringTrue = @("yes", "true", "ok", "y") $stringFalse = @( "no", "false", "n") try { if (-not ($null -eq $Object) ) { switch ($Object.ToString().ToLower()) { {$stringTrue -contains $_} { $result = $true break } {$stringFalse -contains $_} { $result = $false break } default { $result = [System.Boolean]::Parser($Object.ToString()) break } } } } catch { } $result } ================================================ FILE: d365fo.tools/internal/functions/convertto-hashtable.ps1 ================================================  <# .SYNOPSIS Convert an object into a HashTable .DESCRIPTION Convert an object into a HashTable, can be used with json objects to create a HashTable .PARAMETER InputObject The object you want to convert .EXAMPLE PS C:\> $jsonString = '{"Test1": "Test1","Test2": "Test2"}' PS C:\> $jsonString | ConvertFrom-Json | ConvertTo-Hashtable .NOTES Author: Mötz Jensen (@Splaxi) Original Author: Adam Bertram (@techsnips_io) Original blog post with the function explained: https://4sysops.com/archives/convert-json-to-a-powershell-hash-table/ #> function ConvertTo-Hashtable { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseCmdletCorrectly', '')] [CmdletBinding()] param ( [Parameter(ValueFromPipeline)] $InputObject ) process { ## Return null if the input is null. This can happen when calling the function ## recursively and a property is null if ($null -eq $InputObject) { return $null } ## Check if the input is an array or collection. If so, we also need to convert ## those types into hash tables as well. This function will convert all child ## objects into hash tables (if applicable) if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string]) { $collection = @( foreach ($object in $InputObject) { ConvertTo-Hashtable -InputObject $object } ) ## Return the array but don't enumerate it because the object may be pretty complex Write-Output -NoEnumerate $collection } elseif ($InputObject -is [psobject]) { ## If the object has properties that need enumeration ## Convert it to its own hash table and return it $hash = @{} foreach ($property in $InputObject.PSObject.Properties) { $hash[$property.Name] = ConvertTo-Hashtable -InputObject $property.Value } $hash } else { ## If the object isn't an array, collection, or other object, it's already a hash table ## So just return it. $InputObject } } } ================================================ FILE: d365fo.tools/internal/functions/convertto-pscustomobject.ps1 ================================================  <# .SYNOPSIS Convert a Hashtable into a PSCustomObject .DESCRIPTION Convert a Hashtable into a PSCustomObject .PARAMETER InputObject The hashtable you want to convert .EXAMPLE PS C:\> $params = @{SqlUser = ""; SqlPwd = ""} PS C:\> $params | ConvertTo-PsCustomObject This will create a hashtable with 2 properties. It will convert the hashtable into a PSCustomObject .NOTES Author: Mötz Jensen (@Splaxi) Original blog post with the function explained: https://blogs.msdn.microsoft.com/timid/2013/03/05/converting-pscustomobject-tofrom-hashtables/ #> function ConvertTo-PsCustomObject { [OutputType('[PsCustomObject]')] param ( [Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [object[]] $InputObject ) begin { $i = 0 } process { foreach ($myHashtable in $InputObject) { if ($myHashtable.GetType().Name -eq 'hashtable') { $output = New-Object -TypeName PsObject Add-Member -InputObject $output -MemberType ScriptMethod -Name AddNote -Value { Add-Member -InputObject $this -MemberType NoteProperty -Name $args[0] -Value $args[1] } $myHashtable.Keys | Sort-Object | ForEach-Object { $output.AddNote($_, $myHashtable.$_) } $output } elseif ($myHashtable.GetType().Name -eq 'OrderedDictionary') { $output = New-Object -TypeName PsObject Add-Member -InputObject $output -MemberType ScriptMethod -Name AddNote -Value { Add-Member -InputObject $this -MemberType NoteProperty -Name $args[0] -Value $args[1] } $myHashtable.Keys | ForEach-Object { $output.AddNote($_, $myHashtable.$_) } $output } else { Write-PSFMessage -Level Warning -Message "Index `$i is not of type [hashtable]" -Target $i } $i += 1 } } } ================================================ FILE: d365fo.tools/internal/functions/copy-filetolcsblob.ps1 ================================================  <# .SYNOPSIS Copy local file to Azure Blob Storage .DESCRIPTION Copy local file to Azure Blob Storage that is used by LCS .PARAMETER FilePath Path to the file you want to upload to the Azure Blob storage .PARAMETER FullUri The full URI, including SAS token and Policy Permissions to the blob .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Copy-FileToLcsBlob -FilePath "C:\temp\d365fo.tools\GOLDEN.bacpac" -FullUri "https://uswedpl1catalog.blob.core.windows.net/...." This will upload the "C:\temp\d365fo.tools\GOLDEN.bacpac" to the "https://uswedpl1catalog.blob.core.windows.net/...." Blob Storage location. It is required that the FullUri contains all the needed SAS tokens and Policy Permissions for the upload to succeed. .NOTES Tags: Azure Blob, LCS, Upload Author: Mötz Jensen (@Splaxi) #> function Copy-FileToLcsBlob { [CmdletBinding()] [OutputType()] param( [Parameter(Mandatory = $true)] [string]$FilePath, [Parameter(Mandatory = $true)] [System.Uri]$FullUri, [switch] $EnableException ) Invoke-TimeSignal -Start Write-PSFMessage -Level Verbose -Message "Initializing the needed .net objects to work against Azure Blob." -Target $FullUri $cloudblob = New-Object -TypeName Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob -ArgumentList @($FullUri) try { $uploadResult = Get-AsyncResult -Task $cloudblob.UploadFromFileAsync([System.String]$FilePath) } catch { Write-PSFMessage -Level Host -Message "Something went wrong while uploading the desired file to Azure Blob." -Exception $PSItem.Exception -Target $FullUri Stop-PSFFunction -Message "Stopping because of errors" return } Invoke-TimeSignal -End $uploadResult } ================================================ FILE: d365fo.tools/internal/functions/get-applicationenvironment.ps1 ================================================  <# .SYNOPSIS Load all necessary information about the D365 instance .DESCRIPTION Load all servicing dll files from the D365 instance into memory .EXAMPLE PS C:\> Get-ApplicationEnvironment This will load all the different dll files into memory. .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-ApplicationEnvironment { [System.Collections.ArrayList] $Files2Process = New-Object -TypeName "System.Collections.ArrayList" $AOSPath = Join-Path $script:ServiceDrive "\AOSService\webroot\bin" Write-PSFMessage -Level Verbose -Message "Testing if we are running on a AOS server or not." if (-not (Test-Path -Path $AOSPath -PathType Container)) { Write-PSFMessage -Level Verbose -Message "The machine is NOT an AOS server." $MRPath = Join-Path $script:ServiceDrive "MRProcessService\MRInstallDirectory\Server\Services" Write-PSFMessage -Level Verbose -Message "Testing if we are running on a BI / MR server or not." if (-not (Test-Path -Path $MRPath -PathType Container)) { 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 personal workstation / personal computer." return } else { Write-PSFMessage -Level Verbose -Message "The machine is a BI / MR server." $BasePath = $MRPath $null = $Files2Process.Add((Join-Path $script:ServiceDrive "Monitoring\Instrumentation\Microsoft.Dynamics.AX.Authentication.Instrumentation.dll")) } } else { Write-PSFMessage -Level Verbose -Message "The machine is an AOS server." $BasePath = $AOSPath $null = $Files2Process.Add((Join-Path $BasePath "Microsoft.Dynamics.AX.Authentication.Instrumentation.dll")) } 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" $null = $Files2Process.Add((Join-Path $BasePath "Microsoft.Dynamics.AX.Configuration.Base.dll")) $null = $Files2Process.Add((Join-Path $BasePath "Microsoft.Dynamics.BusinessPlatform.SharedTypes.dll")) $null = $Files2Process.Add((Join-Path $BasePath "Microsoft.Dynamics.AX.Framework.EncryptionEngine.dll")) $null = $Files2Process.Add((Join-Path $BasePath "Microsoft.Dynamics.AX.Security.Instrumentation.dll")) $null = $Files2Process.Add((Join-Path $BasePath "Microsoft.Dynamics.ApplicationPlatform.Environment.dll")) Import-AssemblyFileIntoMemory -Path $($Files2Process.ToArray()) -UseTempFolder if (Test-PSFFunctionInterrupt) { return } Write-PSFMessage -Level Verbose -Message "All assemblies loaded. Getting environment details." $environment = [Microsoft.Dynamics.ApplicationPlatform.Environment.EnvironmentFactory]::GetApplicationEnvironment() $environment } ================================================ FILE: d365fo.tools/internal/functions/get-asyncresult.ps1 ================================================  <# .SYNOPSIS Simple abstraction to handle asynchronous executions .DESCRIPTION Simple abstraction to handle asynchronous executions for several other cmdlets .PARAMETER Task The task you want to work / wait for to complete .EXAMPLE PS C:\> $client = New-Object -TypeName System.Net.Http.HttpClient PS C:\> Get-AsyncResult -Task $client.SendAsync($request) This will take the client (http) and have it send a request using the asynchronous pattern. .NOTES Tags: Async, Waiter, Wait Author: Mötz Jensen (@Splaxi) #> function Get-AsyncResult { [CmdletBinding()] [OutputType('Object')] param ( [Parameter(Mandatory = $true, Position = 1)] [object] $Task ) Write-PSFMessage -Level Verbose -Message "Building the Task Waiter and start waiting." -Target $Task $Task.GetAwaiter().GetResult() } ================================================ FILE: d365fo.tools/internal/functions/get-axaggregatedimensions.ps1 ================================================  <# .SYNOPSIS Get Aggregate Dimension .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Aggregate Dimensions .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Get-AxAggregateDimensions This will get all objects. .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> Function Get-AxAggregateDimensions { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param( [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) BEGIN { Import-GenerateReportAssemblies $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $providerConfig.XppMetadataPath = $PackageDirectory $providerConfig.MetadataPath = $PackageDirectory $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig) } PROCESS { $aggregateDimensionsModelInfos = $metadataProvider.AggregateDimensions.GetPrimaryKeysWithModelInfo() foreach ($tuple in $aggregateDimensionsModelInfos) { $elementName = $tuple.Item1 $element = $metadataProvider.AggregateDimensions.Read($elementName) $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair Name = $element.Name DataSource = $element.Table } $outItems } } END {} } ================================================ FILE: d365fo.tools/internal/functions/get-axaggregatemeasures.ps1 ================================================  <# .SYNOPSIS Get Aggregate Measure .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Aggregate Measures .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Get-AxAggregateMeasures This will get all objects. .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> Function Get-AxAggregateMeasures { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param( [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) BEGIN { Import-GenerateReportAssemblies $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $providerConfig.XppMetadataPath = $PackageDirectory $providerConfig.MetadataPath = $PackageDirectory $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig) $aggregateDimensions = Get-AxAggregateDimensions -BinDir $BinDir -PackageDirectory $PackageDirectory $aggregateDimensionsHash = $aggregateDimensions | ArrayToHash } PROCESS { $aggregateMeasurementsModelInfos = $metadataProvider.AggregateMeasurements.GetPrimaryKeysWithModelInfo() foreach ($tuple in $aggregateMeasurementsModelInfos) { $elementName = $tuple.Item1 $element = $metadataProvider.AggregateMeasurements.Read($elementName) foreach ($k in $element.MeasureGroups) { $dimensionsArray = @() #creates an array of dimensions and their data source in parenthesis per MeasureGroup foreach ($i in $k.Dimensions) { $pos = $i.ToString().IndexOf(" ") $i = $i.ToString().Substring(0, $pos) $dimensionsArray += ($i + " (" + $aggregateDimensionsHash[$i].DataSource + ")") } $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair Name = $element.Name MeasureGroup = $k.Name MeasureGroupDataSource = $k.Table Measures = [String]::join(", ", $k.Measures) Dimensions = [String]::join(", ", $dimensionsArray) } $outItems } } } } Function ArrayToHash { param() begin { $hash = @{} } process { $hash[$_.Name] = $_ } end { return $hash } } ================================================ FILE: d365fo.tools/internal/functions/get-axdataentities.ps1 ================================================  <# .SYNOPSIS Get Data Entity .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Data Entities and their fields .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Get-AxDataEntities This will get all objects. .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> Function Get-AxDataEntities { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param( [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) BEGIN { Import-GenerateReportAssemblies $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $providerConfig.XppMetadataPath = $PackageDirectory $providerConfig.MetadataPath = $PackageDirectory $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig) } PROCESS { $dataEntityModelInfos = $metadataProvider.DataEntityViews.GetPrimaryKeysWithModelInfo() foreach ($tuple in $dataEntityModelInfos) { $elementName = $tuple.Item1 $element = $metadataProvider.DataEntityViews.Read($elementName) # # Build list of DataSources # $datasourceList = @() foreach ($datasource in $element.ViewMetadata.DataSources) { $datasourceList += New-Object PSObject -Property @{ # create a hash table of the name/value pair DataSourceName = $datasource.Name DataSourceTable = $datasource.Table } $datasourceList += QueryDataSourceRecursion $datasource.DataSources } # # Convert DataSource list to hash # $dataSourceHash = @{} $datasourceList | ForEach-Object { $dataSourceHash[$_.DataSourceName] = $_ } foreach ($j in $element.Fields) { #filter out system fields if ($j -notlike "AX_*") { $typeName = $j.GetType().Name $field_binding = "" if ($typename -eq "AxDataEntityViewMappedField") { $tableName = "" if ($dataSourceHash.ContainsKey($j.DataSource)) { $tableName = $dataSourceHash[$j.DataSource].DataSourceTable } $field_binding = $j.DataSource + "(" + $tableName + ")." + $j.DataField } elseif ($null -ne $j.IsComputedField -and $null -ne $j.ComputedFieldMethod) { # handle case of AxDataEntityViewUnmappedField{PrimitiveType} $field_binding = "METHOD: " + $j.ComputedFieldMethod } else { Write-PSFMessage -Level "Warning" -Message "Unexpected type $typeName" } $outItems = [PsCustomObject][ordered]@{ # create a hash table of the name/value pair Name = $element.Name Public = $element.IsPublic ODataAccessible = $element.IsPublic PublicCollectionName = $element.PublicCollectionName StagingTable = $element.DataManagementStagingTable EntityCategory = $element.EntityCategory TableGroup = $element.TableGroup Field_Name = $j.Name Field_Binding = $field_binding DataManagementEnabled = $element.DataManagementEnabled } $outItems } } } } } # # Recurse on the AxQuerySimpleEmbeddedDataSource array used by DataEntity under the AxQuerySimpleRootDataSource to return an array of objects # Function QueryDataSourceRecursion ([Microsoft.Dynamics.AX.Metadata.MetaModel.AxQuerySimpleEmbeddedDataSource[]] $queryDataSources) { $datasourceList = @() foreach ($datasource in $queryDataSources) { $datasourceList += [PsCustomObject]@{ # create a hash table of the name/value pair DataSourceName = $datasource.Name DataSourceTable = $datasource.Table } $datasourceList += QueryDataSourceRecursion $datasource.DataSources } $datasourceList } ================================================ FILE: d365fo.tools/internal/functions/get-axforms.ps1 ================================================  <# .SYNOPSIS Get Form .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Forms .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Get-AxForms This will get all objects. .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> Function Get-AxForms { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param( [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) BEGIN { Import-GenerateReportAssemblies $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $providerConfig.XppMetadataPath = $PackageDirectory $providerConfig.MetadataPath = $PackageDirectory $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig) } PROCESS { $formsModelInfos = $metadataProvider.Forms.GetPrimaryKeysWithModelInfo() foreach ($tuple in $formsModelInfos) { $elementName = $tuple.Item1 $element = $metadataProvider.Forms.Read($elementName) $outItems = New-Object PSObject -Property @{ # create a hash table of the name/value pair Name = $element.Name DataSources = $element.DataSources } $outItems } } } ================================================ FILE: d365fo.tools/internal/functions/get-axviews.ps1 ================================================  <# .SYNOPSIS Get View .DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Views .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .PARAMETER PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine .EXAMPLE PS C:\> Get-AxViews This will get all objects. .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE #> Function Get-AxViews { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param( [string] $BinDir = "$Script:BinDir\bin", [string] $PackageDirectory = $Script:PackageDirectory ) BEGIN { Import-GenerateReportAssemblies $providerConfig = New-Object Microsoft.Dynamics.AX.Metadata.Storage.DiskProvider.DiskProviderConfiguration $providerConfig.XppMetadataPath = $PackageDirectory $providerConfig.MetadataPath = $PackageDirectory $providerFactory = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProvider = $providerFactory.CreateDiskProvider($providerConfig) } PROCESS { $viewsModelInfos = $metadataProvider.Views.GetPrimaryKeysWithModelInfo() foreach ($tuple in $viewsModelInfos) { $elementName = $tuple.Item1 $element = $metadataProvider.Views.Read($elementName) $outItems = New-Object PSObject -Property @{ # create a hash table of the name/value pair Name = $element.Name DataSources = $element.ViewMetadata.DataSources } $outItems } } } ================================================ FILE: d365fo.tools/internal/functions/get-azureserviceobjective.ps1 ================================================  <# .SYNOPSIS Get the Azure Service Objectives .DESCRIPTION Get the current tiering details from the Azure SQL Database instance .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-AzureServiceObjective -DatabaseServer dbserver1.database.windows.net -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" This will get the Azure service objective details from the Azure SQL Database instance located at "dbserver1.database.windows.net" .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Get-AzureServiceObjective { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $DatabaseServer, [Parameter(Mandatory = $true)] [string] $DatabaseName, [Parameter(Mandatory = $true)] [string] $SqlUser, [Parameter(Mandatory = $true)] [string] $SqlPwd, [switch] $EnableException ) $Params = Get-DeepClone $PSBoundParameters if($Params.ContainsKey("EnableException")){$null = $Params.Remove("EnableException")} $sqlCommand = Get-SqlCommand @Params -TrustedConnection $false $commandText = (Get-Content "$script:ModuleRoot\internal\sql\get-azureserviceobjective.sql") -join [Environment]::NewLine $sqlCommand.CommandText = $commandText try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $reader = $sqlCommand.ExecuteReader() if ($reader.Read() -eq $true) { Write-PSFMessage -Level Verbose "Extracting details from the result retrieved from the Azure DB instance" $edition = $reader.GetString(1) $serviceObjective = $reader.GetString(2) $reader.close() $sqlCommand.Connection.Close() $sqlCommand.Dispose() [PSCustomObject]@{ DatabaseEdition = $edition DatabaseServiceObjective = $serviceObjective } } else { $messageString = "The query to detect edition and service objectives from the Azure DB instance failed." Write-PSFMessage -Level Host -Message $messageString -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>',''))) return } } catch { $messageString = "Something went wrong while working against the database." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ return } } ================================================ FILE: d365fo.tools/internal/functions/get-backupname.ps1 ================================================  <# .SYNOPSIS Get a backup name for the file .DESCRIPTION Generate a backup name for the file parsed .PARAMETER File Path to the file that you want a backup name for .PARAMETER Suffix The name that you want to put into the new backup file name .EXAMPLE PS C:\> Get-BackupName -File "C:\temp\d365do.tools\Test.txt" -Suffix "Original" The function will return "C:\temp\d365do.tools\Test_Original.txt" .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Get-BackupName { [CmdletBinding()] [OutputType([System.String])] param ( [Parameter(Mandatory = $true)] [string] $File, [Parameter(Mandatory = $true)] [string] $Suffix ) Write-PSFMessage -Level Verbose -Message "Getting backup name for file: $File" -Tag $File $FileInfo = [System.IO.FileInfo]::new($File) $BackupName = "{0}{1}_{2}{3}" -f $FileInfo.Directory, $FileInfo.BaseName, $Suffix, $FileInfo.Extension Write-PSFMessage -Level Verbose -Message "Backup name for the file will be $BackupName" -Tag $BackupName $BackupName } ================================================ FILE: d365fo.tools/internal/functions/get-canonicalidentityprovider.ps1 ================================================  <# .SYNOPSIS Load the Canonical Identity Provider .DESCRIPTION Load the necessary dll files from the D365 instance to get the Canonical Identity Provider object .EXAMPLE PS C:\> Get-CanonicalIdentityProvider This will get the Canonical Identity Provider from the D365 instance .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Get-CanonicalIdentityProvider { [CmdletBinding()] param () try { Write-PSFMessage -Level Verbose "Loading dll files to do some work against the CanonicalIdentityProvider." Add-Type -Path "$Script:AOSPath\bin\Microsoft.Dynamics.AX.Framework.EncryptionEngine.dll" Add-Type -Path "$Script:AOSPath\bin\Microsoft.Dynamics.AX.Security.AuthenticationCommon.dll" Write-PSFMessage -Level Verbose "Executing the CanonicalIdentityProvider lookup logic." $Identity = [Microsoft.Dynamics.AX.Security.AuthenticationCommon.AadHelper]::GetIdentityProvider() $Provider = [Microsoft.Dynamics.AX.Security.AuthenticationCommon.AadHelper]::GetCanonicalIdentityProvider($Identity) Write-PSFMessage -Level Verbose "CanonicalIdentityProvider is: $Provider" -Tag $Provider return $Provider } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the CanonicalIdentityProvider." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } ================================================ FILE: d365fo.tools/internal/functions/get-compilerresult.ps1 ================================================  <# .SYNOPSIS Parse the compiler output .DESCRIPTION Parse the output log files from the compiler and show the number of warnings and errors .PARAMETER Path The path to where the compiler output log file is located .EXAMPLE PS C:\> Get-CompilerResult -Path c:\temp\d365fo.tools\Dynamics.AX.Custom.xppc.log This will analaze the Dynamics.AX.Custom.xppc.log compiler output file. Will create a summarize object with number of errors and warnings. .NOTES Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Vilmos Kintera" (twitter: @DAXRunBase) All credits goes to him for showing how to extract these information His blog can be found here: https://www.daxrunbase.com/blog/ The specific blog post that we based this cmdlet on can be found here: https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/ The github repository containing the original scrips can be found here: https://github.com/DAXRunBase/PowerShell-and-Azure #> function Get-CompilerResult { [CmdletBinding()] [OutputType('[PsCustomObject]')] param ( [parameter(Mandatory = $true)] [string] $Path ) Invoke-TimeSignal -Start if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } $errorText = Select-String -LiteralPath $Path -Pattern ^Errors: | ForEach-Object { $_.Line } $errorCount = [int]$errorText.Split()[-1] $warningText = Select-String -LiteralPath $Path -Pattern ^Warnings: | ForEach-Object { $_.Line } $warningCount = [int]$warningText.Split()[-1] [PsCustomObject][Ordered]@{ File = "$Path" Warnings = $warningCount Errors = $errorCount PSTypeName = 'D365FO.TOOLS.CompilerOutput' } } ================================================ FILE: d365fo.tools/internal/functions/get-deepclone.ps1 ================================================  <# .SYNOPSIS Clone a hashtable .DESCRIPTION Create a deep clone of a hashtable for you to work on it without updating the original object .PARAMETER InputObject The hashtable you want to clone .EXAMPLE PS C:\> Get-DeepClone -InputObject $HashTable This will clone the $HashTable variable into a new object and return it to you. .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-DeepClone { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseOutputTypeCorrectly', '')] [CmdletBinding()] param( [parameter(Mandatory = $true)] $InputObject ) process { if($InputObject -is [hashtable]) { $clone = @{} foreach($key in $InputObject.keys) { if($key -eq "EnableException") {continue} $clone[$key] = Get-DeepClone $InputObject[$key] } $clone } else { $InputObject } } } ================================================ FILE: d365fo.tools/internal/functions/get-fileversion.ps1 ================================================  <# .SYNOPSIS Get the file version details .DESCRIPTION Get the file version details for any given file .PARAMETER Path Path to the file that you want to extract the file version details from .EXAMPLE PS C:\> Get-FileVersion -Path "C:\Program Files\Microsoft Dynamics AX\60\Server\MicrosoftDynamicsAX\Bin\AxServ32.exe" This will get the file version details for the AX AOS executable (AxServ32.exe). .NOTES Author: Mötz Jensen (@Splaxi) Inspired by https://blogs.technet.microsoft.com/askpfeplat/2014/12/07/how-to-correctly-check-file-versions-with-powershell/ #> function Get-FileVersion { [CmdletBinding()] Param( [Parameter(Mandatory = $true)] [string] $Path ) if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } Write-PSFMessage -Level Verbose -Message "Extracting the file properties for: $Path" -Target $Path $Filepath = Get-Item -Path $Path [PSCustomObject]@{ FileVersion = $Filepath.VersionInfo.FileVersion ProductVersion = $Filepath.VersionInfo.ProductVersion FileVersionUpdated = "$($Filepath.VersionInfo.FileMajorPart).$($Filepath.VersionInfo.FileMinorPart).$($Filepath.VersionInfo.FileBuildPart).$($Filepath.VersionInfo.FilePrivatePart)" ProductVersionUpdated = "$($Filepath.VersionInfo.ProductMajorPart).$($Filepath.VersionInfo.ProductMinorPart).$($Filepath.VersionInfo.ProductBuildPart).$($Filepath.VersionInfo.ProductPrivatePart)" } } ================================================ FILE: d365fo.tools/internal/functions/get-identityprovider.ps1 ================================================  <# .SYNOPSIS Get the identity provider .DESCRIPTION Execute a web request to get the identity provider for the given email address .PARAMETER Email Email address on the account that you want to get the Identity Provider details about .EXAMPLE PS C:\> Get-IdentityProvider -Email "Claire@contoso.com" This will get the Identity Provider details for the user account with the email address "Claire@contoso.com" .NOTES Author : Rasmus Andersen (@ITRasmus) Author : Mötz Jensen (@splaxi) #> function Get-IdentityProvider { [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 1)] [string]$Email ) $tenant = Get-TenantFromEmail $Email try { $webRequest = New-WebRequest "https://login.windows.net/$tenant/.well-known/openid-configuration" $null "GET" $response = $WebRequest.GetResponse() if ($response.StatusCode -eq [System.Net.HttpStatusCode]::Ok) { $stream = $response.GetResponseStream() $streamReader = New-Object System.IO.StreamReader($stream); $openIdConfig = $streamReader.ReadToEnd() $streamReader.Close(); } else { $statusDescription = $response.StatusDescription throw "Https status code : $statusDescription" } $openIdConfigJSON = ConvertFrom-Json $openIdConfig $openIdConfigJSON.issuer } catch { Write-PSFMessage -Level Host -Message "Something went wrong while executing the web request" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } ================================================ FILE: d365fo.tools/internal/functions/get-instanceidentityprovider.ps1 ================================================  <# .SYNOPSIS Get the instance provider from the D365FO instance .DESCRIPTION Get the instance provider from the dll files used for encryption and authentication for D365FO .EXAMPLE PS C:\> Get-InstanceIdentityProvider This will return the Instance Identity Provider based on the D365FO instance. .NOTES Author : Rasmus Andersen (@ITRasmus) Author : Mötz Jensen (@splaxi) #> function Get-InstanceIdentityProvider { [CmdletBinding()] [OutputType([System.String])] param() $files = @("$Script:AOSPath\bin\Microsoft.Dynamics.AX.Framework.EncryptionEngine.dll", "$Script:AOSPath\bin\Microsoft.Dynamics.AX.Security.AuthenticationCommon.dll") if (-not (Test-PathExists -Path $files -Type Leaf)) { return } try { Add-Type -Path $files $Identity = [Microsoft.Dynamics.AX.Security.AuthenticationCommon.AadHelper]::GetIdentityProvider() Write-PSFMessage -Level Verbose -Message "The found instance identity provider is: $Identity" -Target $Identity $Identity } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the Identity provider" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } ================================================ FILE: d365fo.tools/internal/functions/get-instancevalues.ps1 ================================================  <# .SYNOPSIS Get the Azure Database instance values .DESCRIPTION Extract the PlanId, TenantId and PlanCapability from the Azure Database instance .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER TrustedConnection Should the connection use a Trusted Connection or not .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-InstanceValues -DatabaseServer SQLServer -DatabaseName AXDB -SqlUser "SqlAdmin" -SqlPwd "Pass@word1" This will extract the PlanId, TenantId and PlanCapability from the AXDB on the SQLServer, using the "SqlAdmin" credentials to do so. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Get-InstanceValues { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] [OutputType('System.Collections.Hashtable')] param ( [Parameter(Mandatory = $true)] [string] $DatabaseServer, [Parameter(Mandatory = $true)] [string] $DatabaseName, [Parameter(Mandatory = $false)] [string] $SqlUser, [Parameter(Mandatory = $false)] [string] $SqlPwd, [Parameter(Mandatory = $false)] [boolean] $TrustedConnection, [switch] $EnableException ) $Params = Get-DeepClone $PSBoundParameters if($Params.ContainsKey("EnableException")){$null = $Params.Remove("EnableException")} $sqlCommand = Get-SqlCommand @Params $commandText = (Get-Content "$script:ModuleRoot\internal\sql\get-instancevalues.sql") -join [Environment]::NewLine $sqlCommand.CommandText = $commandText try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $reader = $sqlCommand.ExecuteReader() if ($reader.Read() -eq $true) { Write-PSFMessage -Level Verbose "Extracting details from the result retrieved from the DB instance" $tenantId = $reader.GetString(0) $planId = $reader.GetGuid(1) $planCapability = $reader.GetString(2) @{ TenantId = $tenantId PlanId = $planId PlanCapability = $planCapability } } else { $messageString = "The query to detect TenantId, PlanId and PlanCapability from the database failed." Write-PSFMessage -Level Host -Message $messageString -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of missing parameters." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>',''))) return } } catch { $messageString = "Something went wrong while working against the database." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ return } finally { $reader.close() $sqlCommand.Connection.Close() $sqlCommand.Dispose() } } ================================================ FILE: d365fo.tools/internal/functions/get-lcsassetfilev2.ps1 ================================================  <# .SYNOPSIS Get information for all assets of a type from the asset library inside a LCS project .DESCRIPTION Get the information for the available file assets of a certain type from the asset library inside a LCS project .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER FileType Type of asset you want to get information for Valid options: "Model" "Process Data Package" "Software Deployable Package" "GER Configuration" "Data Package" "PowerBI Report Model" "E-Commerce Package" "NuGet Package" "Retail Self-Service Package" "Commerce Cloud Scale Unit Extension" .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-LcsAssetFileV2 -ProjectId 123456789 -FileType SoftwareDeployablePackage -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will get all software deployable packages from the Asset Library inside LCS. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The FileType is Software Deployable Packages, with the FileType parameter. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .NOTES Tags: Environment, LCS, Api, AAD, Token, Asset, File, Files Author: Mötz Jensen (@Splaxi) #> function Get-LcsAssetFileV2 { [Cmdletbinding()] param( [Parameter(Mandatory = $true)] [int] $ProjectId, [LcsAssetFileType] $FileType, [Alias('Token')] [string] $BearerToken, [Parameter(Mandatory = $true)] [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $fileTypeValue = [int]$FileType $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "GET" $parms.Uri = "$LcsApiUri/box/fileasset/GetAssets/$($ProjectId)?fileType=$($fileTypeValue)" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in request for listing files from the asset library of LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/get-lcsassetvalidationstatusv2.ps1 ================================================  <# .SYNOPSIS Get the validation status from LCS .DESCRIPTION Get the validation status for a given file in the Asset Library in LCS .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER AssetId The unique id of the asset / file that you are trying to deploy from LCS .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-LcsAssetValidationStatusV2 -ProjectId 123456789 -BearerToken "JldjfafLJdfjlfsalfd..." -AssetId "958ae597-f089-4811-abbd-c1190917eaae" -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will check the file with the AssetId "958ae597-f089-4811-abbd-c1190917eaae" in validated or not. It will test against the Asset Library located under the LCS project 123456789. The BearerToken "JldjfafLJdfjlfsalfd..." is used to authenticate against the LCS API endpoint. The file will be named "ReadyForTesting" inside the Asset Library in LCS. The file is validated against the NON-EUROPE LCS API. .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-LcsAssetValidationStatusV2 { [CmdletBinding()] [OutputType()] param ( [Parameter(Mandatory = $true)] [int] $ProjectId, [Parameter(Mandatory = $true)] [Alias('Token')] [string] $BearerToken, [Parameter(Mandatory = $true)] [string] $AssetId, [Parameter(Mandatory = $true)] [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "GET" $parms.Uri = "$LcsApiUri/box/fileasset/GetFileAssetValidationStatus/$($ProjectId)?assetId=$AssetId" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in request for getting the validation status of an asset in the asset library of LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/get-lcsdatabasebackupsv2.ps1 ================================================  <# .SYNOPSIS Get database backups from LCS project .DESCRIPTION Get the available database backups from the Asset Library in LCS project .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-LcsDatabaseBackupsV2 -ProjectId 123456789 -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will get all available database backups from the Asset Library inside LCS. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .NOTES Tags: Environment, LCS, Api, AAD, Token, Bacpac, Backup Author: Mötz Jensen (@Splaxi) #> function Get-LcsDatabaseBackupsV2 { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [Cmdletbinding()] param( [Parameter(Mandatory = $true)] [int] $ProjectId, [Alias('Token')] [string] $BearerToken, [Parameter(Mandatory = $true)] [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "GET" $parms.Uri = "$LcsApiUri/databasemovement/v1/databases/project/$($ProjectId)" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in request for listing all backup files from the asset library of LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/get-lcsdatabaseoperationstatusv2.ps1 ================================================  <# .SYNOPSIS Get the status of a LCS database operation .DESCRIPTION Get the database operation status for an environment in LCS .PARAMETER Token The token to be used for the http request against the LCS API .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER OperationActivityId The unique id of the action you got from when starting the database operation against the environment .PARAMETER EnvironmentId The unique id of the environment that you want to work against The Id can be located inside the LCS portal .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-LcsDatabaseOperationStatusV2 -ProjectId 123456789 -OperationActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -Token "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will check the database operation status of a specific OperationActivityId against an environment. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .LINK Start-LcsDatabaseRefresh .NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deployable Package Author: Mötz Jensen (@Splaxi) #> function Get-LcsDatabaseOperationStatusV2 { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Cmdletbinding()] param( [Parameter(Mandatory = $true)] [int] $ProjectId, [Alias('Token')] [string] $BearerToken, [Parameter(Mandatory = $true)] [string] $OperationActivityId, [Parameter(Mandatory = $true)] [string] $EnvironmentId, [Parameter(Mandatory = $true)] [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "GET" $parms.Uri = "$LcsApiUri/databasemovement/v1/fetchstatus/project/$($ProjectId)/environment/$($EnvironmentId)/operationactivity/$($OperationActivityId)" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in request for getting the status of a database operation in LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/get-lcsdeploymentstatusv2.ps1 ================================================  <# .SYNOPSIS Get the status of a LCS deployment .DESCRIPTION Get the deployment status for an environment in LCS .PARAMETER Token The token to be used for the http request against the LCS API .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER ActivityId The unique id of the action you got from when starting the deployment to the environment .PARAMETER EnvironmentId The unique id of the environment that you want to work against The Id can be located inside the LCS portal .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-LcsDeploymentStatusV2 -ProjectId 123456789 -Token "Bearer JldjfafLJdfjlfsalfd..." -ActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -LcsApiUri "https://lcsapi.lcs.dynamics.com" 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. The http request will be using the "Bearer JldjfafLJdfjlfsalfd..." token for authentication against the LCS API. The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .LINK Start-LcsDeployment .NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deployable Package Author: Mötz Jensen (@Splaxi) #> function Get-LcsDeploymentStatusV2 { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Cmdletbinding()] param( [Parameter(Mandatory = $true)] [int] $ProjectId, [Alias('Token')] [string] $BearerToken, [Parameter(Mandatory = $true)] [string] $ActivityId, [Parameter(Mandatory = $true)] [string] $EnvironmentId, [Parameter(Mandatory = $true)] [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "GET" $parms.Uri = "$LcsApiUri/environment/v2/fetchstatus/project/$($ProjectId)/environment/$($EnvironmentId)/operationactivity/$($ActivityId)" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in request for getting the status of a deployment in LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/get-lcsenvironmenthistory.ps1 ================================================  <# .SYNOPSIS Get history for a given environment within a LCS project .DESCRIPTION Get history details for a given environment from within a LCS project There can be multiple pages of data, which requires you to use the TraverseAllPages parameter, if you want all data to be shown .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER EnvironmentId The unique id of the environment that you want to work against The Id can be located inside the LCS portal .PARAMETER Page Page number that you want to request from the LCS API This is part of the initial request, which helps you navigate more data - when it is available .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-LcsEnvironmentHistory -ProjectId 123456789 -Token "Bearer JldjfafLJdfjlfsalfd..." -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will list the first page of environment history data from the LCS API. The ProjectId "123456789" is the desired project. The Token "Bearer JldjfafLJdfjlfsalfd..." is the authentication to be used. The EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" is the specific environment that we want history data from. The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-LcsEnvironmentHistory { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [int] $ProjectId, [Alias('Token')] [string] $BearerToken, [string] $EnvironmentId, [int] $Page, [Parameter(Mandatory = $true)] [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "GET" $parms.Uri = "$LcsApiUri/environmentinfo/v1/history/project/$($ProjectId)/environment/$EnvironmentId" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout if ($Page) { $parms.Uri += "/?page=$Page" } } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in request for getting the environment history in LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/get-lcsenvironmentmetadata.ps1 ================================================  <# .SYNOPSIS Get LCS environment meta data from within a project .DESCRIPTION Get all meta data details for environments from within a LCS project It supports listing all environments, but also supports single / specific environments by searching based on EnvironmentId or EnvironmentName .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER EnvironmentId The unique id of the environment that you want to work against The Id can be located inside the LCS portal Either you want to utilize the EnvironmentId parameter or you can utilize the EnvironmentName parameter, only one of them is valid in a request .PARAMETER EnvironmentName The unique name of the environment that you want to work against The Id can be located inside the LCS portal Either you want to utilize the EnvironmentName parameter or you can utilize the EnvironmentId parameter, only one of them is valid in a request .PARAMETER Page Page number that you want to request from the LCS API This is part of the initial request, which helps you navigate more data - when it is available .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-LcsEnvironmentMetadata -ProjectId 123456789 -Token "Bearer JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will list the first page of environment metadata from the LCS API, across all available environments. The ProjectId "123456789" is the desired project. The Token "Bearer JldjfafLJdfjlfsalfd..." is the authentication to be used. The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .EXAMPLE PS C:\> Get-LcsEnvironmentMetadata -ProjectId 123456789 -Token "Bearer JldjfafLJdfjlfsalfd..." -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will list the first page of environment metadata from the LCS API. The ProjectId "123456789" is the desired project. The Token "Bearer JldjfafLJdfjlfsalfd..." is the authentication to be used. The EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" is the specific environment that we want metadata from. The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .EXAMPLE PS C:\> Get-LcsEnvironmentMetadata -ProjectId 123456789 -Token "Bearer JldjfafLJdfjlfsalfd..." -EnvironmentName "Contoso-SIT" -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will list the first page of environment metadata from the LCS API. The ProjectId "123456789" is the desired project. The Token "Bearer JldjfafLJdfjlfsalfd..." is the authentication to be used. The EnvironmentName "Contoso-SIT" is the specific environment that we want metadata from. The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-LcsEnvironmentMetadata { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] # [CmdletBinding()] [CmdletBinding(DefaultParameterSetName = 'Default')] param( [Parameter(Mandatory = $true)] [int] $ProjectId, [Alias('Token')] [string] $BearerToken, [Parameter(ParameterSetName = 'SearchByEnvironmentId')] [string] $EnvironmentId, [Parameter(ParameterSetName = 'SearchByEnvironmentName')] [string] $EnvironmentName, [Parameter(ParameterSetName = 'Pagination')] [int] $Page, [Parameter(Mandatory = $true)] [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "GET" $parms.Uri = "$LcsApiUri/environmentinfo/v1/detail/project/$($ProjectId)" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout if ($PSCmdlet.ParameterSetName -eq "Pagination") { $parms.Uri += "/?page=$Page" } elseif ($PSCmdlet.ParameterSetName -eq "SearchByEnvironmentId") { $parms.Uri += "/?environmentId=$EnvironmentId" } elseif ($PSCmdlet.ParameterSetName -eq "SearchByEnvironmentName") { $parms.Uri += "/?environmentName=$EnvironmentName" } } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in request for getting the environment metadata a project in LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/get-lcsenvironmentrsatcertificate.ps1 ================================================  <# .SYNOPSIS Get LCS environment rsat certificate from within a project .DESCRIPTION Download and persist the active rsat certificate from environments from within a LCS project .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER EnvironmentId The unique id of the environment that you want to work against The Id can be located inside the LCS portal .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Get-LcsEnvironmentRsatCertificate -ProjectId 123456789 -Token "Bearer JldjfafLJdfjlfsalfd..." -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will get the raw rsat details for the environment from the LCS API. The ProjectId "123456789" is the desired project. The Token "Bearer JldjfafLJdfjlfsalfd..." is the authentication to be used. The EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" is the specific environment that we want the rsat certificate details from. The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-LcsEnvironmentRsatCertificate { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] # [CmdletBinding()] [CmdletBinding(DefaultParameterSetName = 'Default')] param( [Parameter(Mandatory = $true)] [int] $ProjectId, [Alias('Token')] [Parameter(Mandatory = $true)] [string] $BearerToken, [Parameter(Mandatory = $true)] [string] $EnvironmentId, [Parameter(Mandatory = $true)] [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "GET" $parms.Uri = "$LcsApiUri/environmentinfo/v1/rsatdownload/project/$($ProjectId)/environment/$EnvironmentId" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in request for getting the environment rsat certificate in LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/get-lcsfileasset.ps1 ================================================  <# .SYNOPSIS Get information for a single asset from the project or shared asset library of LCS .DESCRIPTION Get the information for an available file asset from the project or shared asset library of LCS .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER AssetId Id of the asset you want to get information for .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts Usually this parameter is not used directly, but via the Enable-D365Exception cmdlet See https://github.com/d365collaborative/d365fo.tools/wiki/Exception-handling#what-does-the--enableexception-parameter-do for further information .EXAMPLE PS C:\> Get-LcsFileAsset -ProjectId 123456789 -AssetId "e70cac82-6a7c-4f9e-a8b9-e707b961e986" -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will get the information of the asset identified by the asset id. 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. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .NOTES Tags: Environment, LCS, Api, AAD, Token, Asset, File, Files Author: Florian Hopfner (@FH-Inway) #> function Get-LcsFileAsset { [Cmdletbinding()] param( [Parameter(Mandatory = $true)] [int] $ProjectId, [Parameter(Mandatory = $true)] [string] $AssetId, [Alias('Token')] [string] $BearerToken, [Parameter(Mandatory = $true)] [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "GET" $parms.Uri = "$LcsApiUri/box/fileasset/GetFileAsset/$($ProjectId)?assetId=$($AssetId)" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in request for file asset from the shared asset library of LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/get-lcssharedassetfile.ps1 ================================================  <# .SYNOPSIS Get information for all assets of a type from the shared asset library of LCS .DESCRIPTION Get the information for the available file assets of a certain type from the shared asset library of LCS .PARAMETER FileType Type of file you want to get information for Valid options: "Model" "Process Data Package" "Software Deployable Package" "GER Configuration" "Data Package" "PowerBI Report Model" "E-Commerce Package" "NuGet Package" "Retail Self-Service Package" "Commerce Cloud Scale Unit Extension" .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on which LCS shared asset library you want to query. There are multiple valid URI's / URL's. Not that not all file types may be available in all URIs. Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts Usually this parameter is not used directly, but via the Enable-D365Exception cmdlet See https://github.com/d365collaborative/d365fo.tools/wiki/Exception-handling#what-does-the--enableexception-parameter-do for further information .EXAMPLE PS C:\> Get-LcsSharedAssetFile -FileType SoftwareDeployablePackage -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will get all software deployable packages from the shared asset library of LCS. The FileType is Software Deployable Packages, with the FileType parameter. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .NOTES Tags: Environment, LCS, Api, AAD, Token, Asset, File, Files Author: Florian Hopfner (@FH-Inway) #> function Get-LcsSharedAssetFile { [Cmdletbinding()] param( [LcsAssetFileType] $FileType, [Alias('Token')] [string] $BearerToken, [Parameter(Mandatory = $true)] [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $fileTypeValue = [int]$FileType $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "GET" $parms.Uri = "$LcsApiUri/box/fileasset/GetSharedAssets?fileType=$($fileTypeValue)" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in request for listing files from the shared asset library of LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/get-loginfromemail.ps1 ================================================  <# .SYNOPSIS Get the login name from the e-mail address .DESCRIPTION Extract the login name from the e-mail address by substring everything before the @ character .PARAMETER Email The e-mail address that you want to get the login name from .EXAMPLE PS C:\> Get-LoginFromEmail -Email Claire@contoso.com This will substring the e-mail address and return "Claire" as the result .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Get-LoginFromEmail { [CmdletBinding()] [OutputType('System.String')] param ( [string]$Email ) $email.Substring(0, $Email.LastIndexOf('@')).Trim() } ================================================ FILE: d365fo.tools/internal/functions/get-networkdomain.ps1 ================================================  <# .SYNOPSIS Get the network domain from the e-mail .DESCRIPTION Get the network domain provider (Azure) for the e-mail / user .PARAMETER Email The e-mail that you want to retrieve the provider for .EXAMPLE PS C:\> Get-NetworkDomain -Email "Claire@contoso.com" This will return the provider registered with the "Claire@contoso.com" e-mail address. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Get-NetworkDomain { [CmdletBinding()] [OutputType('System.String')] param( [Parameter(Mandatory = $true, Position = 1)] [string]$Email ) $tenant = Get-TenantFromEmail $Email $provider = Get-InstanceIdentityProvider $canonicalIdentityProvider = Get-CanonicalIdentityProvider if ($Provider.ToLower().Contains($Tenant.ToLower()) -eq $True) { $canonicalIdentityProvider } else { "$canonicalIdentityProvider$Tenant" } } ================================================ FILE: d365fo.tools/internal/functions/get-productinfoprovider.ps1 ================================================  <# .SYNOPSIS Get the product information .DESCRIPTION Get the product information object from the environment .EXAMPLE PS C:\> Get-ProductInfoProvider This will get the product information object and return it .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Get-ProductInfoProvider { #!HACK: This can't be solved like we use to - it loads dependent assemblies based on path, when you invoke the method. Add-Type -Path "$Script:AOSPath\bin\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.dll" [Microsoft.Dynamics.BusinessPlatform.ProductInformation.Provider.ProductInfoProvider]::get_Provider() } ================================================ FILE: d365fo.tools/internal/functions/get-servicelist.ps1 ================================================  <# .SYNOPSIS Get the list of Dynamics 365 services .DESCRIPTION Get the list of Dynamics 365 service names based on the parameters .PARAMETER All Switch to instruct the cmdlet to output all service names .PARAMETER Aos Switch to instruct the cmdlet to output the aos service name .PARAMETER Batch Switch to instruct the cmdlet to output the batch service name .PARAMETER FinancialReporter Switch to instruct the cmdlet to output the financial reporter service name .PARAMETER DMF Switch to instruct the cmdlet to output the data management service name .EXAMPLE PS C:\> Get-ServiceList -All This will return all services for an D365 environment .NOTES Author: Mötz Jensen (@Splaxi) #> Function Get-ServiceList { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueSwitchParameter", "")] [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, ParameterSetName = 'Default', Position = 2 )] [switch] $All = $true, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 2 )] [switch] $Aos, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 3 )] [switch] $Batch, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 4 )] [switch] $FinancialReporter, [Parameter(Mandatory = $false, ParameterSetName = 'Specific', Position = 5 )] [switch] $DMF ) if ($PSCmdlet.ParameterSetName -eq "Specific") { $All = $false } Write-PSFMessage -Level Verbose -Message "The PSBoundParameters was" -Target $PSBoundParameters $aosname = "w3svc" $batchname = "DynamicsAxBatch" $financialname = "MR2012ProcessService" $dmfname = "Microsoft.Dynamics.AX.Framework.Tools.DMF.SSISHelperService.exe" [System.Collections.ArrayList]$Services = New-Object -TypeName "System.Collections.ArrayList" if ($All) { $null = $Services.AddRange(@($aosname, $batchname, $financialname, $dmfname)) } else { if ($Aos) { $null = $Services.Add($aosname) } if ($Batch) { $null = $Services.Add($batchname) } if ($FinancialReporter) { $null = $Services.Add($financialname) } if ($DMF) { $null = $Services.Add($dmfname) } } $Services.ToArray() } ================================================ FILE: d365fo.tools/internal/functions/get-sqlcommand.ps1 ================================================  <# .SYNOPSIS Get a SqlCommand object .DESCRIPTION Get a SqlCommand object initialized with the passed parameters .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER TrustedConnection Should the connection use a Trusted Connection or not .PARAMETER NoPooling Should the connection use connection pooling or not .EXAMPLE PS C:\> Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" -TrustedConnection $true This will initialize a new SqlCommand object (.NET type) with localhost as the server name, AxDB as the database and the User123 sql credentials. .EXAMPLE PS C:\> Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" -TrustedConnection $true -NoPooling This will initialize a new SqlCommand object (.NET type) with localhost as the server name, AxDB as the database and the User123 sql credentials. The connection will not use connection pooling. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Get-SQLCommand { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string] $DatabaseServer, [Parameter(Mandatory = $true)] [string] $DatabaseName, [Parameter(Mandatory = $false)] [string] $SqlUser, [Parameter(Mandatory = $false)] [string] $SqlPwd, [Parameter(Mandatory = $false)] [boolean] $TrustedConnection, [switch] $NoPooling ) Write-PSFMessage -Level Debug -Message "Writing the bound parameters" -Target $PsBoundParameters [System.Collections.ArrayList]$Params = New-Object -TypeName "System.Collections.ArrayList" $null = $Params.Add("Server='$DatabaseServer';") $null = $Params.Add("Database='$DatabaseName';") # We have learned that closing a connection is not enough to closing the connection. if ($NoPooling) { $null = $Params.Add("Pooling=false;") } if ($null -eq $TrustedConnection -or (-not $TrustedConnection)) { $null = $Params.Add("User='$SqlUser';") $null = $Params.Add("Password='$SqlPwd';") } else { $null = $Params.Add("Integrated Security='SSPI';") } $null = $Params.Add("Application Name='d365fo.tools'") Write-PSFMessage -Level Verbose -Message "Building the SQL connection string." -Target ($Params -join ",") $sqlConnection = New-Object System.Data.SqlClient.SqlConnection try { $sqlConnection.ConnectionString = ($Params -join "") $sqlCommand = New-Object System.Data.SqlClient.SqlCommand $sqlCommand.Connection = $sqlConnection $sqlCommand.CommandTimeout = 0 } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working with the sql server connection objects" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } $sqlCommand } ================================================ FILE: d365fo.tools/internal/functions/get-sqlparametersize.ps1 ================================================  <# .SYNOPSIS Get the size from the parameter .DESCRIPTION Get the size from the parameter based on its datatype and value .PARAMETER SqlParameter The SqlParameter object that you want to get the size from .EXAMPLE PS C:\> $SqlCmd = New-Object System.Data.SqlClient.SqlCommand PS C:\> $SqlCmd.Parameters.AddWithValue("@Parm1", "1234") PS C:\> Get-SqlParameterSize -SqlParameter $SqlCmd.Parameters[0] This will extract the size from the first parameter from the SqlCommand object and return it as a formatted string. .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-SqlParameterSize { [CmdletBinding()] [OutputType('System.String')] param ( [System.Data.SqlClient.SqlParameter] $SqlParameter ) $res = "" $stringSizeTypes = @( [System.Data.SqlDbType]::Char, [System.Data.SqlDbType]::NChar, [System.Data.SqlDbType]::NText, [System.Data.SqlDbType]::NVarChar, [System.Data.SqlDbType]::Text, [System.Data.SqlDbType]::VarChar ) if ( $stringSizeTypes -contains $SqlParameter.SqlDbType) { $res = "($($SqlParameter.Size))" } $res } ================================================ FILE: d365fo.tools/internal/functions/get-sqlparametervalue.ps1 ================================================  <# .SYNOPSIS Get the value from the parameter .DESCRIPTION Get the value that is assigned to the SqlParameter object .PARAMETER SqlParameter The SqlParameter object that you want to work against .EXAMPLE PS C:\> $SqlCmd = New-Object System.Data.SqlClient.SqlCommand PS C:\> $SqlCmd.Parameters.AddWithValue("@Parm1", "1234") PS C:\> Get-SqlParameterValue -SqlParameter $SqlCmd.Parameters[0] This will extract the value from the first parameter from the SqlCommand object. .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-SqlParameterValue { [CmdletBinding()] [OutputType('System.String')] param ( [System.Data.SqlClient.SqlParameter] $SqlParameter ) $result = $null $stringEscaped = @( [System.Data.SqlDbType]::Char, [System.Data.SqlDbType]::DateTime, [System.Data.SqlDbType]::NChar, [System.Data.SqlDbType]::NText, [System.Data.SqlDbType]::NVarChar, [System.Data.SqlDbType]::Text, [System.Data.SqlDbType]::VarChar, [System.Data.SqlDbType]::Xml, [System.Data.SqlDbType]::Date, [System.Data.SqlDbType]::Time, [System.Data.SqlDbType]::DateTime2, [System.Data.SqlDbType]::DateTimeOffset ) $stringNumbers = @([System.Data.SqlDbType]::Float, [System.Data.SqlDbType]::Decimal) switch ($SqlParameter.SqlDbType) { { $stringEscaped -contains $_ } { $result = "'{0}'" -f $SqlParameter.Value.ToString().Replace("'", "''") break } { [System.Data.SqlDbType]::Bit } { if ((ConvertTo-BooleanOrDefault -Object $SqlParameter.Value.ToString() -Default $true)) { $result = '1' } else { $result = '0' } break } { $stringNumbers -contains $_ } { $SqlParameter.Value $result = ([System.Double]$SqlParameter.Value).ToString([System.Globalization.CultureInfo]::InvariantCulture).Replace("'", "''") break } default { $result = $SqlParameter.Value.ToString().Replace("'", "''") break } } $result } ================================================ FILE: d365fo.tools/internal/functions/get-sqlstring.ps1 ================================================  <# .SYNOPSIS Get an executable string from a SqlCommand object .DESCRIPTION Get an formatted and valid string from a SqlCommand object that contains all variables .PARAMETER SqlCommand The SqlCommand object that you want to retrieve the string from .EXAMPLE PS C:\> $SqlCmd = New-Object System.Data.SqlClient.SqlCommand PS C:\> $SqlCmd.CommandText = "SELECT * FROM Table WHERE Column = @Parm1" PS C:\> $SqlCmd.Parameters.AddWithValue("@Parm1", "1234") PS C:\> Get-SqlString -SqlCommand $SqlCmd .NOTES Author: Mötz Jensen (@Splaxi) #> function Get-SqlString { [CmdletBinding()] [OutputType('System.String')] param ( [System.Data.SqlClient.SqlCommand] $SqlCommand ) $sbDeclare = [System.Text.StringBuilder]::new() $sbAssignment = [System.Text.StringBuilder]::new() $sbRes = [System.Text.StringBuilder]::new() if ($SqlCommand.CommandType -eq [System.Data.CommandType]::Text) { if (-not ($null -eq $SqlCommand.Connection)) { $null = $sbDeclare.Append("USE [").Append($SqlCommand.Connection.Database).AppendLine("]") } foreach ($parameter in $SqlCommand.Parameters) { if ($parameter.Direction -eq [System.Data.ParameterDirection]::Input) { $null = $sbDeclare.Append("DECLARE ").Append($parameter.ParameterName).Append("`t") $null = $sbDeclare.Append($parameter.SqlDbType.ToString().ToUpper()) $null = $sbDeclare.AppendLine((Get-SqlParameterSize -SqlParameter $parameter)) $null = $sbAssignment.Append("SET ").Append($parameter.ParameterName).Append(" = ").AppendLine((Get-SqlParameterValue -SqlParameter $parameter)) } } $null = $sbRes.AppendLine($sbDeclare.ToString()) $null = $sbRes.AppendLine($sbAssignment.ToString()) $null = $sbRes.AppendLine($SqlCommand.CommandText) } $sbRes.ToString() } ================================================ FILE: d365fo.tools/internal/functions/get-syncelements.ps1 ================================================  <# .SYNOPSIS Retrieve sync base and extension elements based on a modulename .DESCRIPTION Retrieve the list of installed packages / modules where the name fits the ModuleName parameter. For every model retrieved: collect all base sync and extension sync elements. .PARAMETER ModuleName Name of the module that you are looking for Accepts wildcards for searching. E.g. -Name "Application*Adaptor" Default value is "*" which will search for all modules .EXAMPLE PS C:\> Get-SyncElements -ModuleName "Application*Adaptor" Retrieve the list of installed packages / modules where the name fits the search "Application*Adaptor". For every model retrieved: collect all base sync and extension sync elements. .NOTES Tags: Database Author: Jasper Callens - Cegeka #> function Get-SyncElements { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] Param( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [string] $ModuleName ) begin { $assemblies2Process = New-Object -TypeName "System.Collections.ArrayList" $null = $assemblies2Process.Add((Join-Path $BinDirTools "Microsoft.Dynamics.AX.Metadata.dll")) $null = $assemblies2Process.Add((Join-Path $BinDirTools "Microsoft.Dynamics.AX.Metadata.Core.dll")) $null = $assemblies2Process.Add((Join-Path $BinDirTools "Microsoft.Dynamics.AX.Metadata.Storage.dll")) $null = $assemblies2Process.Add((Join-Path $BinDirTools "Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll")) $null = $assemblies2Process.Add((Join-Path $BinDirTools "Microsoft.Dynamics.AX.Metadata.Management.Delta.dll")) $null = $assemblies2Process.Add((Join-Path $BinDirTools "Microsoft.Dynamics.AX.Metadata.Management.Core.dll")) $null = $assemblies2Process.Add((Join-Path $BinDirTools "Microsoft.Dynamics.AX.Metadata.Management.Merge.dll")) $null = $assemblies2Process.Add((Join-Path $BinDirTools "Microsoft.Dynamics.AX.Metadata.Management.Diff.dll")) Import-AssemblyFileIntoMemory -Path $($assemblies2Process.ToArray()) $runtimeMetadataProvider = (New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory).CreateRuntimeProvider($Script:PackageDirectory) $baseSyncElements = New-Object -TypeName "System.Collections.ArrayList" $extensionSyncElements = New-Object -TypeName "System.Collections.ArrayList" $extensionToBaseSyncElements = New-Object -TypeName "System.Collections.ArrayList" } process { Write-PSFMessage -Level Debug -Message "Collecting $ModuleName AOT elements to sync" $baseSyncElements.AddRange($runtimeMetadataProvider.Tables.ListObjects($ModuleName)); $baseSyncElements.AddRange($runtimeMetadataProvider.Views.ListObjects($ModuleName)); $baseSyncElements.AddRange($runtimeMetadataProvider.DataEntityViews.ListObjects($ModuleName)); $extensionSyncElements.AddRange($runtimeMetadataProvider.TableExtensions.ListObjects($ModuleName)); # Some Extension elements have to be 'converted' to their base element that has to be passed to the SyncList of the syncengine # Add these elements to an ArrayList $extensionToBaseSyncElements.AddRange($runtimeMetadataProvider.ViewExtensions.ListObjects($ModuleName)); $extensionToBaseSyncElements.AddRange($runtimeMetadataProvider.DataEntityViewExtensions.ListObjects($ModuleName)); } end { # Loop every extension element, convert it to its base element and add the base element to another list Foreach ($extElement in $extensionToBaseSyncElements) { $null = $baseSyncElements.Add($extElement.Substring(0, $extElement.IndexOf('.'))) } Write-PSFMessage -Level Debug -Message "Elements from $ModuleName retrieved: $(($baseSyncElements + $extensionSyncElements) -join ",")" [PSCustomObject]@{ BaseSyncElements = $baseSyncElements.ToArray(); ExtensionSyncElements = $extensionSyncElements.ToArray(); } } } ================================================ FILE: d365fo.tools/internal/functions/get-tenantfromemail.ps1 ================================================  <# .SYNOPSIS Get the tenant from e-mail address .DESCRIPTION Get the tenant (domain) from an e-mail address .PARAMETER Email The e-mail address you want to get the tenant from .EXAMPLE PS C:\> Get-TenantFromEmail -Email "Claire@contoso.com" This will return the tenant (domain) from the "Claire@contoso.com" e-mail address. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Get-TenantFromEmail { [CmdletBinding()] [OutputType('System.String')] param ( [string] $email ) $email.Substring($email.LastIndexOf('@') + 1).Trim(); } ================================================ FILE: d365fo.tools/internal/functions/get-timezone.ps1 ================================================  <# .SYNOPSIS Get time zone .DESCRIPTION Extract the time zone object from the supplied parameter Uses regex to determine whether or not the parameter is the ID or the DisplayName of a time zone .PARAMETER InputObject String value that you want converted into a time zone object .EXAMPLE PS C:\> Get-TimeZone -InputObject "UTC" This will return the time zone object based on the UTC id. .NOTES Tag: Time, TimeZone, Author: Mötz Jensen (@Splaxi) #> function Get-TimeZone { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidOverwritingBuiltInCmdlets", "")] [CmdletBinding()] [OutputType('System.TimeZoneInfo')] param ( [Parameter(Mandatory = $true, Position = 1)] [string] $InputObject ) if ($InputObject -match "\s\-\s\[") { $search = [regex]::Split($InputObject, "\s\-\s\[")[0] [System.TimeZoneInfo]::GetSystemTimeZones() | Where-Object {$PSItem.DisplayName -eq $search} | Select-Object -First 1 } else { try { [System.TimeZoneInfo]::FindSystemTimeZoneById($InputObject) } catch { Write-PSFMessage -Level Host -Message "Unable to translate the $InputObject to a known .NET timezone value. Please make sure you filled in a valid timezone." Stop-PSFFunction -Message "Stopping because timezone wasn't found." -StepsUpward 1 return } } } ================================================ FILE: d365fo.tools/internal/functions/get-usersidfromaad.ps1 ================================================  <# .SYNOPSIS Get the SID from an Azure Active Directory (AAD) user .DESCRIPTION Get the generated SID that an Azure Active Directory (AAD) user will get in relation to Dynamics 365 Finance & Operations environment .PARAMETER SignInName The sign in name (email address) for the user that you want the SID from .PARAMETER Provider The provider connected to the sign in name .EXAMPLE PS C:\> Get-UserSIDFromAad -SignInName "Claire@contoso.com" -Provider "ZXY" This will get the SID for Azure Active Directory user "Claire@contoso.com" .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Get-UserSIDFromAad { [CmdletBinding()] [OutputType('System.String')] param ( [string] $SignInName, [string] $Provider ) try { $productDetails = Get-ProductInfoProvider Add-Type -Path "$Script:AOSPath\bin\Microsoft.Dynamics.BusinessPlatform.SharedTypes.dll" Add-Type -Path "$Script:AOSPath\bin\Microsoft.Dynamics.ApplicationPlatform.PerformanceCounters.dll" Add-Type -Path "$Script:AOSPath\bin\Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll" Add-Type -Path "$Script:AOSPath\bin\Microsoft.Dynamics.AX.Security.SidGenerator.dll" if ($([Version]$productDetails.ApplicationVersion) -ge $([Version]"10.0.13")) { $SID = [Microsoft.Dynamics.Ax.Security.SidGenerator]::Generate($SignInName, $Provider, [Microsoft.Dynamics.Ax.Security.SidGenerator+SidAlgorithm]::Sha1) } else { $SID = [Microsoft.Dynamics.Ax.Security.SidGenerator]::Generate($SignInName, $Provider) } Write-PSFMessage -Level Verbose -Message "Generated SID: $SID" -Target $SID $SID } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } } ================================================ FILE: d365fo.tools/internal/functions/get-windowsdefenderstatus.ps1 ================================================  <# .SYNOPSIS Get Windows Defender Status .DESCRIPTION Will get the current status of the Windows Defender .PARAMETER Silent Instruct the cmdlet to silence the output written to the console If set the output will be silenced, if not set, the output will be written to the console .EXAMPLE PS C:\> Get-WindowsDefenderStatus This will get the status of Windows Defender. It will write the output to the console. .EXAMPLE PS C:\> Get-WindowsDefenderStatus -Silent This will get the status of Windows Defender. All outputs will be silenced. .NOTES Inspired by https://gallery.technet.microsoft.com/scriptcenter/PowerShell-to-Check-if-811b83bc Author: Robin Kretzschmar (@darksmile92) Author: Mötz Jensen (@Splaxi) #> function Get-WindowsDefenderStatus { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] [OutputType('System.Boolean')] param ( [switch] $Silent ) try { $defenderOptions = Get-MpComputerStatus if ([string]::IsNullOrEmpty($defenderOptions)) { if ($Silent -eq $false) { Write-PSFMessage -Level Host -Message "Windows Defender was not found running on the Server: $($env:computername)" } $false } else { if ($Silent -eq $false) { Write-PSFHostColor -DefaultColor "Cyan" -String "Windows Defender was found on the Server: $($env:computername)" Write-PSFHostColor -DefaultColor "Yellow" -String " Is Windows Defender Enabled? $($defenderOptions.AntivirusEnabled)" Write-PSFHostColor -DefaultColor "Yellow" -String " Is Windows Defender Service Enabled? $($defenderOptions.AMServiceEnabled)" Write-PSFHostColor -DefaultColor "Yellow" -String " Is Windows Defender Antispyware Enabled? $($defenderOptions.AntispywareEnabled)" Write-PSFHostColor -DefaultColor "Yellow" -String " Is Windows Defender OnAccessProtection Enabled? $($defenderOptions.OnAccessProtectionEnabled)" Write-PSFHostColor -DefaultColor "Yellow" -String " Is Windows Defender RealTimeProtection Enabled? $($defenderOptions.RealTimeProtectionEnabled)" } if ($defenderOptions.AntivirusEnabled -eq $true) { $true } else { $false } } } catch { if ($Silent -eq $false) { Write-PSFMessage -Level Host -Message "Windows Defender was not found running on the Server: $($env:computername)" } $false } } ================================================ FILE: d365fo.tools/internal/functions/import-aadapplicationIntod365fo.ps1 ================================================  <# .SYNOPSIS Import an Azure Active Directory (AAD) application .DESCRIPTION Import an Azure Active Directory (AAD) application into a Dynamics 365 for Finance & Operations environment .PARAMETER SqlCommand The SQL Command object that should be used when importing the AAD application .PARAMETER Name The name that the imported application should have inside the D365FO environment .PARAMETER UserId The id of the user linked to the application inside the D365FO environment .PARAMETER ClientId The Client ID that the imported application should use inside the D365FO environment .EXAMPLE PS C:\> $SqlCommand = Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" PS C:\> Import-AadApplicationIntoD365FO -SqlCommand $SqlCommand -Name "Application1" -UserId "admin" -ClientId "aef2e67c-64a3-4c72-9294-d288c5bf503d" This will get a SqlCommand object that will connect to the localhost server and the AXDB database, with the sql credential "User123". 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. .NOTES Author: Gert Van Der Heyden (@gertvdheyden) #> function Import-AadApplicationIntoD365FO { [CmdletBinding()] param ( [System.Data.SqlClient.SqlCommand] $SqlCommand, [string] $Name, [string] $UserId, [string] $ClientId ) Write-PSFMessage -Level Verbose -Message "Testing the userid $UserId" $idExists = Test-AadUserIdInD365FO $sqlCommand $UserId if ($idExists -eq $true) { New-D365FOAadApplication $sqlCommand $Name $UserId $ClientId Write-PSFMessage -Level Host -Message "Application $Name for user $UserId added to D365FO" } else { Write-PSFMessage -Level Host -Message "An User with ID = '$UserId' does not exists" } } ================================================ FILE: d365fo.tools/internal/functions/import-aaduserIntod365fo.ps1 ================================================  <# .SYNOPSIS Import an Azure Active Directory (AAD) user .DESCRIPTION Import an Azure Active Directory (AAD) user into a Dynamics 365 for Finance & Operations environment .PARAMETER SqlCommand The SQL Command object that should be used when importing the AAD user .PARAMETER SignInName The sign in name (email address) for the user that you want to import .PARAMETER Name The name that the imported user should have inside the D365FO environment .PARAMETER Id The ID that the imported user should have inside the D365FO environment .PARAMETER SID The SID that correlates to the imported user inside the D365FO environment .PARAMETER StartUpCompany The default company (legal entity) for the imported user .PARAMETER IdentityProvider The provider for the imported to validated against .PARAMETER NetworkDomain The network domain of the imported user .PARAMETER ObjectId The Azure Active Directory object id for the imported user .PARAMETER Language Language that should be configured for the user, for when they sign-in to the D365 environment .EXAMPLE PS C:\> $SqlCommand = Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" 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" This will get a SqlCommand object that will connect to the localhost server and the AXDB database, with the sql credential "User123". 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. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Import-AadUserIntoD365FO { [CmdletBinding()] param ( [System.Data.SqlClient.SqlCommand] $SqlCommand, [string] $SignInName, [string] $Name, [string] $Id, [string] $SID, [string] $StartUpCompany, [string] $IdentityProvider, [string] $NetworkDomain, [string] $ObjectId, [string] $Language ) Write-PSFMessage -Level Verbose -Message "Testing the Email $signInName" -Target $signInName $UserFound = Test-AadUserInD365FO $sqlCommand $SignInName if ($UserFound -eq $false) { Write-PSFMessage -Level Verbose -Message "Testing the userid $Id" -Target $Id $idTaken = Test-AadUserIdInD365FO $sqlCommand $id if (Test-PSFFunctionInterrupt) { return } if ($idTaken -eq $false) { $userAdded = New-D365FOUser $sqlCommand $SignInName $Name $Id $Sid $StartUpCompany $IdentityProvider $NetworkDomain $ObjectId $Language if ($userAdded -eq $true) { $securityAdded = Add-AadUserSecurity $sqlCommand $Id Write-PSFMessage -Level Host -Message "User $SignInName Imported" if ($securityAdded -eq $false) { Write-PSFMessage -Level Host -Message "User $SignInName did not get securityRoles" #Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 #return } } else { Write-PSFMessage -Level Host -Message "User $SignInName, not added to D365FO" #Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 #return } } else { Write-PSFMessage -Level Host -Message "An User with ID = '$ID' already exists" #Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 #return } } else { Write-PSFMessage -Level Host -Message "An User with Email $SignInName already exists in D365FO" #Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 #return } } ================================================ FILE: d365fo.tools/internal/functions/import-assemblyfileintomemory.ps1 ================================================  <# .SYNOPSIS Imports a .NET dll file into memory .DESCRIPTION Imports a .NET dll file into memory, by creating a copy (temporary file) and imports it using reflection .PARAMETER Path Path to the dll file you want to import Accepts an array of strings .PARAMETER UseTempFolder Instruct the cmdlet to create the file copy in the default temp folder This switch can be used, if writing to the original folder is not wanted or not possible .EXAMPLE PS C:\> Import-AssemblyFileIntoMemory -Path "C:\AOSService\PackagesLocalDirectory\Bin\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Framework.dll" This will create an new file named "C:\AOSService\PackagesLocalDirectory\Bin\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Framework.dll_shawdow.dll" The new file is then imported into memory using .NET Reflection. After the file has been imported, it will be deleted from disk. .EXAMPLE PS C:\> Import-AssemblyFileIntoMemory -Path "C:\AOSService\PackagesLocalDirectory\Bin\Microsoft.Dynamics.BusinessPlatform.ProductInformation.Framework.dll" -UseTempFolder This will create an new file named "Microsoft.Dynamics.BusinessPlatform.ProductInformation.Framework.dll_shawdow.dll" in the temp folder The new file is then imported into memory using .NET Reflection. After the file has been imported, it will be deleted from disk. .NOTES Author: Mötz Jensen (@Splaxi) #> function Import-AssemblyFileIntoMemory { [CmdletBinding()] [OutputType()] param ( [Parameter(Mandatory = $true, Position = 1)] [string[]] $Path, [switch] $UseTempFolder ) if (-not (Test-PathExists -Path $Path -Type Leaf)) { Stop-PSFFunction -Message "Stopping because unable to locate file." -StepsUpward 1 return } foreach ($itemPath in $Path) { if ($UseTempFolder) { $filename = Split-Path -Path $itemPath -Leaf $shadowClonePath = Join-Path $env:TEMP "$filename`_shadow.dll" } else { $shadowClonePath = "$itemPath`_shadow.dll" } try { Write-PSFMessage -Level Debug -Message "Cloning $itemPath to $shadowClonePath" Copy-Item -Path $itemPath -Destination $shadowClonePath -Force Write-PSFMessage -Level Debug -Message "Loading $shadowClonePath into memory" $null = [AppDomain]::CurrentDomain.Load(([System.IO.File]::ReadAllBytes($shadowClonePath))) } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" return } finally { Write-PSFMessage -Level Debug -Message "Removing $shadowClonePath" Remove-Item -Path $shadowClonePath -Force -ErrorAction SilentlyContinue } } } ================================================ FILE: d365fo.tools/internal/functions/import-generatereportassemblies.ps1 ================================================  <# .SYNOPSIS Import assemblies needed for the metat report generation .DESCRIPTION Import all assemblies that are needed to work with the meta data provider for all related objects .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin .EXAMPLE PS C:\> Import-GenerateReportAssemblies This will import all needed assemblies into memory. .NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) #> function Import-GenerateReportAssemblies { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] param ( [string] $BinDir = "$Script:BinDir\bin" ) end { $Files2Process = New-Object System.Collections.Generic.List[string] $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Management.Delta.dll")) $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Management.Diff.dll")) $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Management.Merge.dll")) $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Management.Core.dll")) $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.dll")) $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Core.dll")) $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Storage.dll")) $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll")) $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Metadata.Extensions.dll")) $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Server.Core.dll")) $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Xpp.AxShared.dll")) $Files2Process.Add((Join-Path $BinDir "Microsoft.Dynamics.AX.Xpp.Support.dll")) Import-AssemblyFileIntoMemory -Path $($Files2Process.ToArray()) } } ================================================ FILE: d365fo.tools/internal/functions/invoke-azurebackuprestore.ps1 ================================================  <# .SYNOPSIS Create a database copy in Azure SQL Database instance .DESCRIPTION Create a new database by cloning a database in Azure SQL Database instance .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER NewDatabaseName Name of the new / cloned database in the Azure SQL Database instance .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Invoke-AzureBackupRestore -DatabaseServer TestServer.database.windows.net -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" -NewDatabaseName ExportClone This will create a database named "ExportClone" in the "TestServer.database.windows.net" Azure SQL Database instance. It uses the SQL credential "User123" to preform the needed actions. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> Function Invoke-AzureBackupRestore { [CmdletBinding()] [OutputType('System.Boolean')] param ( [Parameter(Mandatory = $true)] [string] $DatabaseServer, [Parameter(Mandatory = $true)] [string] $DatabaseName, [Parameter(Mandatory = $true)] [string] $SqlUser, [Parameter(Mandatory = $true)] [string] $SqlPwd, [Parameter(Mandatory = $true)] [string] $NewDatabaseName, [switch] $EnableException ) Invoke-TimeSignal -Start $StartTime = Get-Date $SqlConParams = @{DatabaseServer = $DatabaseServer; SqlUser = $SqlUser; SqlPwd = $SqlPwd; TrustedConnection = $false} $sqlCommand = Get-SqlCommand @SqlConParams -DatabaseName $DatabaseName $commandText = (Get-Content "$script:ModuleRoot\internal\sql\newazuredbfromcopy.sql") -join [Environment]::NewLine $commandText = $commandText.Replace('@CurrentDatabase', $DatabaseName) $commandText = $commandText.Replace('@NewName', $NewDatabaseName) $sqlCommand.CommandText = $commandText try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) Write-PSFMessage -Level Verbose -Message "Starting the cloning process of the Azure DB." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $null = $sqlCommand.ExecuteNonQuery() } catch { $messageString = "Something went wrong while cloning the Azure DB database." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ -StepsUpward 1 return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } $sqlCommand = Get-SqlCommand @SqlConParams -DatabaseName "master" $commandText = (Get-Content "$script:ModuleRoot\internal\sql\checkfornewazuredb.sql") -join [Environment]::NewLine $sqlCommand.CommandText = $commandText $null = $sqlCommand.Parameters.Add("@NewName", $NewDatabaseName) $null = $sqlCommand.Parameters.Add("@Time", $StartTime) try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) Write-PSFMessage -Level Verbose -Message "Start to wait for the cloning process of the Azure DB to complete." $sqlCommand.Connection.Open() $operation_row_count = 0 #Loop every minute until we get a row, if we get a row copy is done while ($operation_row_count -eq 0) { $Reader = $sqlCommand.ExecuteReader() $Datatable = New-Object System.Data.DataTable $Datatable.Load($Reader) $operation_row_count = $Datatable.Rows.Count $time = (Get-Date).ToString("HH:mm:ss") Write-PSFMessage -Level Verbose -Message "Cloning not complete Sleeping for 60 seconds. [$time]" Start-Sleep -s 60 } $true } catch { $messageString = "Something went wrong while waiting for the clone process of the Azure DB database to complete." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ -StepsUpward 1 return } finally { $Reader.close() if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() $Datatable.Dispose() } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/internal/functions/invoke-clearazurespecificobjects.ps1 ================================================  <# .SYNOPSIS Clear Azure SQL Database specific objects .DESCRIPTION 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 .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Invoke-ClearAzureSpecificObjects -DatabaseServer TestServer.database.windows.net -DatabaseName ExportClone -SqlUser User123 -SqlPwd "Password123" This will execute all necessary scripts against the "ExportClone" database that exists in the "TestServer.database.windows.net" Azure SQL Database instance. It uses the SQL credential "User123" to preform the needed actions. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> Function Invoke-ClearAzureSpecificObjects { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [string] $DatabaseServer, [Parameter(Mandatory = $true)] [string] $DatabaseName, [Parameter(Mandatory = $true)] [string] $SqlUser, [Parameter(Mandatory = $true)] [string] $SqlPwd, [switch] $EnableException ) $Params = Get-DeepClone $PSBoundParameters if($Params.ContainsKey("EnableException")){$null = $Params.Remove("EnableException")} $sqlCommand = Get-SqlCommand @Params -TrustedConnection $false $commandText = (Get-Content "$script:ModuleRoot\internal\sql\clear-azurebacpacdatabase.sql") -join [Environment]::NewLine $commandText = $commandText.Replace("@NewDatabase", $DatabaseName) $sqlCommand.CommandText = $commandText try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $null = $sqlCommand.ExecuteNonQuery() $true } catch { $messageString = "Something went wrong while clearing the Azure specific objects in the database." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ -StepsUpward 1 return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } } ================================================ FILE: d365fo.tools/internal/functions/invoke-clearsqlspecificobjects.ps1 ================================================  <# .SYNOPSIS Clear SQL Server (on-premises) specific objects .DESCRIPTION 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 .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER TrustedConnection Should the connection use a Trusted Connection or not .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Invoke-ClearSqlSpecificObjects -DatabaseServer localhost -DatabaseName ExportClone -SqlUser User123 -SqlPwd "Password123" This will execute all necessary scripts against the "ExportClone" database that exists in the localhost SQL Server instance. It uses the SQL credential "User123" to preform the needed actions. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> Function Invoke-ClearSqlSpecificObjects { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [string] $DatabaseServer, [Parameter(Mandatory = $true)] [string] $DatabaseName, [Parameter(Mandatory = $false)] [string] $SqlUser, [Parameter(Mandatory = $false)] [string] $SqlPwd, [Parameter(Mandatory = $false)] [boolean] $TrustedConnection, [switch] $EnableException ) $Params = Get-DeepClone $PSBoundParameters if($Params.ContainsKey("EnableException")){$null = $Params.Remove("EnableException")} $sqlCommand = Get-SqlCommand @Params $commandText = (Get-Content "$script:ModuleRoot\internal\sql\clear-sqlbacpacdatabase.sql") -join [Environment]::NewLine $sqlCommand.CommandText = $commandText try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $null = $sqlCommand.ExecuteNonQuery() $true } catch { $messageString = "Something went wrong while clearing the SQL specific objects in the database." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ -StepsUpward 1 return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } } ================================================ FILE: d365fo.tools/internal/functions/invoke-compilerresultanalyzer.ps1 ================================================  <# .SYNOPSIS Analyze the compiler output log .DESCRIPTION Analyze the compiler output log and generate an excel file contain worksheets per type: Errors, Warnings, Tasks It could be a Visual Studio compiler log or it could be a Invoke-D365ModuleCompile log you want analyzed .PARAMETER Path Path to the compiler log file that you want to work against A BuildModelResult.log or a Dynamics.AX.*.xppc.log file will both work .PARAMETER Identifier Identifier used to name the error output when hitting parsing errors .PARAMETER OutputPath Path where you want the excel file (xlsx-file) saved to .PARAMETER SkipWarnings Instructs the cmdlet to skip warnings while analyzing the compiler output log file .PARAMETER SkipTasks Instructs the cmdlet to skip tasks while analyzing the compiler output log file .PARAMETER PackageDirectory Path to the directory containing the installed package / module .EXAMPLE 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" This will analyze the compiler log file and generate a compiler result excel file. .NOTES Tags: Compiler, Build, Errors, Warnings, Tasks Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Vilmos Kintera" (twitter: @DAXRunBase) All credits goes to him for showing how to extract these information His blog can be found here: https://www.daxrunbase.com/blog/ The specific blog post that we based this cmdlet on can be found here: https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/ The github repository containing the original scrips can be found here: https://github.com/DAXRunBase/PowerShell-and-Azure #> function Invoke-CompilerResultAnalyzer { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidAssignmentToAutomaticVariable", "")] [CmdletBinding()] [OutputType('')] param ( [string] $Path, [string] $Identifier, [string] $OutputPath, [switch] $SkipWarnings, [switch] $SkipTasks, [string] $PackageDirectory ) Invoke-TimeSignal -Start if (-not (Test-PathExists -Path $PackageDirectory -Type Container)) { return } $positionRegex = '(?=\[\().*(?=\)\])' $positionSplitRegex = '(.*)(?=\[\().*(?:\)\]: )(.*)' $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:|)(.*)(?:: )(.*)' $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:|)(.*)(?:: )(.*)' $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:|)(.*)(?:: )(.*)' $warningObjects = New-Object System.Collections.Generic.List[System.Object] $errorObjects = New-Object System.Collections.Generic.List[System.Object] $taskObjects = New-Object System.Collections.Generic.List[System.Object] if (-not $SkipWarnings) { Write-PSFMessage -Level Verbose -Message "Will analyze for warnings in the log file." -Target $SkipWarnings try { $warningText = Select-String -LiteralPath $Path -Pattern '(^.*) Warning: (.*)' | ForEach-Object { $_.Line } # Skip modules that do not have warnings if ($warningText) { Write-PSFMessage -Level Verbose -Message "Found warning lines in the log file." foreach ($line in $warningText) { $lineLocal = $line # Remove positioning text in the format of "[(5,5),(5,39)]: " for methods if ($lineLocal -match $positionRegex) { Write-PSFMessage -Level Verbose -Message "Position notation was found in the warning line. Will remove it." $lineReplaced = [regex]::Split($lineLocal, $positionSplitRegex) $lineLocal = $lineReplaced[1] + $lineReplaced[2] } try { Write-PSFMessage -Level Verbose -Message "Will split the warning line, and create result object." # Regular expression matching to split line details into groups $Matches = [regex]::split($lineLocal, $warningRegex) $object = [PSCustomObject]@{ OutputType = $Matches[1].trim() ObjectType = $Matches[2].trim() Path = $Matches[3].trim() Text = $Matches[4].trim() } $warningObjects.Add($object) } catch { Write-PSFHostColor -Level Host "($Identifier) Error during processing line for warnings <$line>" } } } } catch { Write-PSFMessage -Level Host "Error while processing warnings" } } if (-not $SkipTasks) { Write-PSFMessage -Level Verbose -Message "Will analyze for tasks in the log file." -Target $SkipTasks try { $taskText = Select-String -LiteralPath $Path -Pattern '(^.*)TaskListItem Information: (.*)' | ForEach-Object { $_.Line } # Skip modules that do not have tasks if ($taskText) { Write-PSFMessage -Level Verbose -Message "Found task lines in the log file." foreach ($line in $taskText) { $lineLocal = $line # Remove positioning text in the format of "[(5,5),(5,39)]: " for methods if ($lineLocal -match $positionRegex) { Write-PSFMessage -Level Verbose -Message "Position notation was found in the task line. Will remove it." $lineReplaced = [regex]::Split($lineLocal, $positionSplitRegex) $lineLocal = $lineReplaced[1] + $lineReplaced[2] } # Remove TODO part if ($lineLocal -match '(?:TODO :|TODO:|TODO)') { Write-PSFMessage -Level Verbose -Message "TODO prefix string value was found in the line. Will remove it." $lineReplaced = [regex]::Split($lineLocal, '(.*)(?:TODO :|TODO:|TODO)(.*)', [System.Text.RegularExpressions.RegexOptions]::IgnoreCase) $lineLocal = $lineReplaced[1] + $lineReplaced[2] } try { Write-PSFMessage -Level Verbose -Message "Will split the task line, and create result object." # Regular expression matching to split line details into groups $Matches = [regex]::split($lineLocal, $taskRegex) $object = [PSCustomObject]@{ OutputType = $Matches[1].trim() ObjectType = $Matches[2].trim() Path = $Matches[3].trim() Text = $Matches[4].trim() } $taskObjects.Add($object) } catch { Write-PSFHostColor -Level Host "($Identifier) Error during processing line for tasks <$line>" } } } } catch { Write-PSFMessage -Level Host -Message "Error during processing tasks" } } try { $errorText = Select-String -LiteralPath $Path -Pattern '(^.*) Error: (.*)' | ForEach-Object { $_.Line } # Skip modules that do not have errors if ($errorText) { foreach ($line in $errorText) { $lineLocal = $line # Remove positioning text in the format of "[(5,5),(5,39)]: " for methods if ($lineLocal -match $positionRegex) { Write-PSFMessage -Level Verbose -Message "Position notation was found in the error line. Will remove it." $lineReplaced = [regex]::Split($lineLocal, $positionSplitRegex) $lineLocal = $lineReplaced[1] + $lineReplaced[2] } try { Write-PSFMessage -Level Verbose -Message "Will split the error line, and create result object." # Regular expression matching to split line details into groups $Matches = [regex]::split($lineLocal, $errorRegex) $object = [PSCustomObject]@{ ErrorType = $Matches[1].trim() ObjectType = $Matches[2].trim() Path = $Matches[3].trim() Text = $Matches[4].trim() } $errorObjects.Add($object) } catch { Write-PSFHostColor -Level Host "($Identifier) Error during processing line for errors <$line>" } } } } catch { Write-PSFMessage -Level Host -Message "Error during processing errors" } Write-PSFMessage -Level Verbose -Message "Will start exporting the details to the excel file." -Target $OutputPath $errorObjects.ToArray() | Export-Excel -Path $OutputPath -WorksheetName "Errors" -ClearSheet -AutoFilter -AutoSize -BoldTopRow $groupErrorTexts = $errorObjects.ToArray() | Group-Object -Property Text | Sort-Object -Property "Count" -Descending | Select-PSFObject Count, "Name as DistinctErrorText" $groupErrorTexts | Export-Excel -Path $OutputPath -WorksheetName "Errors-Summary" -ClearSheet -AutoFilter -AutoSize -BoldTopRow if (-not $SkipWarnings) { Write-PSFMessage -Level Verbose -Message "Building the warning details and saving them to the excel file." -Target $SkipWarnings $warningObjects.ToArray() | Export-Excel -Path $OutputPath -WorksheetName "Warnings" -ClearSheet -AutoFilter -AutoSize -BoldTopRow $groupWarningTexts = $warningObjects.ToArray() | Group-Object -Property Text | Sort-Object -Property "Count" -Descending | Select-PSFObject Count, "Name as DistinctWarningText" $groupWarningTexts | Export-Excel -Path $OutputPath -WorksheetName "Warnings-Summary" -ClearSheet -AutoFilter -AutoSize -BoldTopRow } else { Remove-Worksheet -Path $OutputPath -WorksheetName "Warnings" Remove-Worksheet -Path $OutputPath -WorksheetName "Warnings-Summary" } if (-not $SkipTasks) { Write-PSFMessage -Level Verbose -Message "Building the task details and saving them to the excel file." -Target $SkipTasks $taskObjects.ToArray() | Export-Excel -Path $OutputPath -WorksheetName "Tasks" -ClearSheet -AutoFilter -AutoSize -BoldTopRow $groupTaskTexts = $taskObjects.ToArray() | Group-Object -Property Text | Sort-Object -Property "Count" -Descending | Select-PSFObject Count, "Name as DistinctTaskText" $groupTaskTexts | Export-Excel -Path $OutputPath -WorksheetName "Tasks-Summary" -ClearSheet -AutoFilter -AutoSize -BoldTopRow } else { Remove-Worksheet -Path $OutputPath -WorksheetName "Tasks" Remove-Worksheet -Path $OutputPath -WorksheetName "Tasks-Summary" } [PSCustomObject]@{ File = $OutputPath Filename = $(Split-Path -Path $OutputPath -Leaf) } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/internal/functions/invoke-modelutil.ps1 ================================================  <# .SYNOPSIS Invoke the ModelUtil.exe .DESCRIPTION A cmdlet that wraps some of the cumbersome work into a streamlined process .PARAMETER Command Instruct the cmdlet to what process you want to execute against the ModelUtil tool Valid options: Import Export Delete Replace .PARAMETER Path Used for import to point where to import from Used for export to point where to export the model to The cmdlet only supports an already extracted ".axmodel" file .PARAMETER Model Name of the model that you want to work against Used for export to select the model that you want to export Used for delete to select the model that you want to delete .PARAMETER BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin Default value is fetched from the current configuration on the machine .PARAMETER MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory .PARAMETER LogPath The path where the log file(s) will be saved .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .EXAMPLE PS C:\> Invoke-ModelUtil -Command Import -Path "c:\temp\d365fo.tools\CustomModel.axmodel" This will execute the import functionality of ModelUtil.exe and have it import the "CustomModel.axmodel" file. .EXAMPLE PS C:\> Invoke-ModelUtil -Command Export -Path "c:\temp\d365fo.tools" -Model CustomModel This will execute the export functionality of ModelUtil.exe and have it export the "CustomModel" model. The file will be placed in "c:\temp\d365fo.tools". .EXAMPLE PS C:\> Invoke-ModelUtil -Command Delete -Model CustomModel This will execute the delete functionality of ModelUtil.exe and have it delete the "CustomModel" model. The folders in PackagesLocalDirectory for the "CustomModel" will NOT be deleted .EXAMPLE PS C:\> Invoke-ModelUtil -Command Replace -Path "c:\temp\d365fo.tools\CustomModel.axmodel" This will execute the replace functionality of ModelUtil.exe and have it replace the "CustomModel" model. .NOTES Tags: AXModel, Model, ModelUtil, Servicing, Import, Export, Delete, Replace Author: Mötz Jensen (@Splaxi) #> function Invoke-ModelUtil { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidDefaultValueSwitchParameter", "")] [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $true)] [ValidateSet('Import', 'Export', 'Delete', 'Replace')] [string] $Command, [Parameter(Mandatory = $True, ParameterSetName = 'Import', Position = 1 )] [Parameter(Mandatory = $True, ParameterSetName = 'Export', Position = 1 )] [Alias('File')] [string] $Path, [Parameter(Mandatory = $True, ParameterSetName = 'Export', Position = 2 )] [Parameter(Mandatory = $True, ParameterSetName = 'Delete', Position = 1 )] [string] $Model, [string] $BinDir = "$Script:PackageDirectory\bin", [string] $MetaDataDir = "$Script:MetaDataDir", [string] $LogPath, [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly ) Invoke-TimeSignal -Start if (-not (Test-PathExists -Path $MetaDataDir, $BinDir -Type Container)) { Stop-PSFFunction -Message "Stopping because of missing paths." -StepsUpward 1 } $executable = Join-Path -Path $BinDir -ChildPath "ModelUtil.exe" if (-not (Test-PathExists -Path $executable -Type Leaf)) { Stop-PSFFunction -Message "Stopping because of missing paths." -StepsUpward 1 } $params = New-Object System.Collections.Generic.List[string] Write-PSFMessage -Level Verbose -Message "Building the parameter options." switch ($Command.ToLowerInvariant()) { 'import' { if (-not (Test-PathExists -Path $Path -Type Leaf)) { Stop-PSFFunction -Message "Stopping because of missing paths." -StepsUpward 1 } $params.Add("-import") $params.Add("-metadatastorepath=`"$MetaDataDir`"") $params.Add("-file=`"$Path`"") } 'export' { $params.Add("-export") $params.Add("-metadatastorepath=`"$MetaDataDir`"") $params.Add("-outputpath=`"$Path`"") $params.Add("-modelname=`"$Model`"") } 'delete' { $params.Add("-delete") $params.Add("-metadatastorepath=`"$MetaDataDir`"") $params.Add("-modelname=`"$Model`"") } 'replace' { if (-not (Test-PathExists -Path $Path -Type Leaf)) { Stop-PSFFunction -Message "Stopping because of missing paths." -StepsUpward 1 } $params.Add("-replace") $params.Add("-metadatastorepath=`"$MetaDataDir`"") $params.Add("-file=`"$Path`"") } } Write-PSFMessage -Level Verbose -Message "Starting the $executable with the parameter options." -Target $($params.ToArray() -join " ") Invoke-Process -Executable $executable -Params $params.ToArray() -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath if (Test-PSFFunctionInterrupt) { Stop-PSFFunction -Message "Stopping because of 'ModelUtil.exe' failed its execution." -StepsUpward 1 return } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/internal/functions/invoke-process.ps1 ================================================  <# .SYNOPSIS Invoke a process .DESCRIPTION Invoke a process and pass the needed parameters to it .PARAMETER Path Path to the program / executable that you want to start .PARAMETER Params Array of string parameters that you want to pass to the executable .PARAMETER LogPath The path where the log file(s) will be saved .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE 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" This will invoke the "C:\AOSService\PackagesLocalDirectory\Bin\xppc.exe" executable. All parameters will be passed to it. The standard output will be redirected to a local variable. The error output will be redirected to a local variable. The standard output will be written to the verbose stream before exiting. If an error should occur, both the standard output and error output will be written to the console / host. .EXAMPLE 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" This will invoke the "C:\AOSService\PackagesLocalDirectory\Bin\xppc.exe" executable. All parameters will be passed to it. The standard output will be outputted directly to the console / host. The error output will be outputted directly to the console / host. .NOTES Author: Mötz Jensen (@Splaxi) https://stackoverflow.com/questions/24370814/how-to-capture-process-output-asynchronously-in-powershell/36539226#36539226 #> function Invoke-Process { [CmdletBinding()] [OutputType()] param ( [Parameter(Mandatory = $true)] [Alias('Executable')] [string] $Path, [Parameter(Mandatory = $true)] [string[]] $Params, [string] $LogPath, [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly, [switch] $EnableException ) Invoke-TimeSignal -Start if (-not (Test-PathExists -Path $Path -Type Leaf)) { return } if (Test-PSFFunctionInterrupt) { return } $tool = Split-Path -Path $Path -Leaf $pinfo = New-Object System.Diagnostics.ProcessStartInfo $pinfo.FileName = "$Path" $pinfo.WorkingDirectory = Split-Path -Path $Path -Parent if (-not $ShowOriginalProgress) { Write-PSFMessage -Level Verbose "Output and Error streams will be redirected (silence mode)" $pinfo.RedirectStandardError = $true $pinfo.RedirectStandardOutput = $true } $pinfo.UseShellExecute = $false $pinfo.Arguments = "$($Params -join " ")" $p = New-Object System.Diagnostics.Process $p.StartInfo = $pinfo Write-PSFMessage -Level Verbose "Starting the $tool" -Target "$($params -join " ")" if ($OutputCommandOnly) { Write-PSFMessage -Level Host "$Path $($pinfo.Arguments)" return } $p.Start() | Out-Null if (-not $ShowOriginalProgress) { $outTask = $p.StandardOutput.ReadToEndAsync(); $errTask = $p.StandardError.ReadToEndAsync(); } Write-PSFMessage -Level Verbose "Waiting for the $tool to complete" $p.WaitForExit() if (-not $ShowOriginalProgress) { $stdout = $outTask.Result $stderr = $errTask.Result } if ($p.ExitCode -ne 0 -and (-not $ShowOriginalProgress)) { Write-PSFMessage -Level Host "Exit code from $tool indicated an error happened. Will output both standard stream and error stream." Write-PSFMessage -Level Host "Standard output was: \r\n $stdout" Write-PSFMessage -Level Host "Error output was: \r\n $stderr" $messageString = "Stopping because an Exit Code from $tool wasn't 0 (zero) like expected." Stop-PSFFunction -Message "Stopping because of Exit Code." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -StepsUpward 1 return } else { Write-PSFMessage -Level Verbose "Standard output was: \r\n $stdout" } if ((-not $ShowOriginalProgress) -and (-not ([string]::IsNullOrEmpty($LogPath)))) { if (-not (Test-PathExists -Path $LogPath -Type Container -Create)) { return } $stdOutputPath = Join-Path -Path $LogPath -ChildPath "$tool`_StdOutput.log" $errOutputPath = Join-Path -Path $LogPath -ChildPath "$tool`_ErrOutput.log" $stdout | Out-File -FilePath $stdOutputPath -Encoding utf8 -Force $stderr | Out-File -FilePath $errOutputPath -Encoding utf8 -Force } Invoke-TimeSignal -End if (-not $ShowOriginalProgress) { [PSCustomObject]@{ stdout = $stdout stderr = $stderr ExitCode = $p.ExitCode } } } ================================================ FILE: d365fo.tools/internal/functions/invoke-requesthandler.ps1 ================================================  <# .SYNOPSIS Invoke the Invoke-RestMethod, wrapped in a handler that helps with the 429 issues .DESCRIPTION A http endpoint will push back on clients, if it feels overwhelmed This translates into 429 in the status code of the http call and requires local logic to respect the retry timeout advice sent back .PARAMETER Method The http method that you want to utilize .PARAMETER Uri The Uri for the endpoint that you want to work against .PARAMETER ContentType The content type value that you want to utilize while working against the endpoint .PARAMETER Payload The payload, if any, that you want to pass to the endpoint .PARAMETER Headers Headers to be used against the endpoint .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .EXAMPLE 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....." } This will post/invoke the stop action for a given environnment in LCS API endpoint. .NOTES Author: Mötz Jensen (@Splaxi) #> function Invoke-RequestHandler { [CmdletBinding()] param ( [Alias("HttpMethod")] [string] $Method, [string] $Uri, [string] $ContentType, [string] $Payload, [Hashtable] $Headers, [Timespan] $RetryTimeout = "00:00:00" ) begin { $parms = @{} $parms.Method = $Method $parms.Uri = $Uri $parms.Headers = $Headers $parms.ContentType = $ContentType if ($Payload) { $parms.Body = $Payload } $start = (Get-Date) $handleTimeout = $false if ($RetryTimeout.Ticks -gt 0) { $handleTimeout = $true } } process { $429Attempts = 0 do { $429Retry = $false try { Invoke-RestMethod @parms } catch [System.Net.WebException] { if ($_.exception.response.statuscode -eq 429) { $429Retry = $true $retryWaitSec = $_.exception.response.Headers["Retry-After"] if (-not ($retryWaitSec -gt 0)) { $retryWaitSec = 10 } if ($handleTimeout) { $timeSinceStart = New-TimeSpan -End $(Get-Date) -Start $start $timeWithWait = $timeSinceStart.Add([timespan]::FromSeconds($retryWaitSec)) $temp = $RetryTimeout - $timeWithWait if ($temp.Ticks -lt 0) { #We will be exceeding the timeout limit $messageString = "The timeout value suggested from the endpoint will exceed the RetryTimeout ($RetryTimeout) threshold." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target $entity Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ -StepsUpward 1 return } } Write-PSFMessage -Level Host -Message "Hit a 429 status code. Will wait for: $retryWaitSec seconds before trying again. Attempt ($429Attempts)" Start-Sleep -Seconds $retryWaitSec $429Attempts++ } else { Throw } } } while ($429Retry) } } ================================================ FILE: d365fo.tools/internal/functions/invoke-sqlbackuprestore.ps1 ================================================  <# .SYNOPSIS Backup & Restore SQL Server database .DESCRIPTION Backup a database and restore it back into the SQL Server .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER TrustedConnection Should the connection use a Trusted Connection or not .PARAMETER NewDatabaseName Name of the new (restored) database .PARAMETER BackupDirectory Path to a directory that can store the backup file .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Invoke-SqlBackupRestore -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" -NewDatabaseName "ExportClone" -BackupDirectory "C:\temp\d365fo.tools\sqlbackup" This will backup the AxDB database and place the backup file inside the "c:\temp\d365fo.tools\sqlbackup" directory. The backup file will the be used to restore into a new database named "ExportClone". .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> Function Invoke-SqlBackupRestore { [CmdletBinding()] [OutputType('System.Boolean')] param ( [Parameter(Mandatory = $true)] [string] $DatabaseServer, [Parameter(Mandatory = $true)] [string] $DatabaseName, [Parameter(Mandatory = $false)] [string] $SqlUser, [Parameter(Mandatory = $false)] [string] $SqlPwd, [Parameter(Mandatory = $false)] [boolean] $TrustedConnection, [Parameter(Mandatory = $true)] [string] $NewDatabaseName, [Parameter(Mandatory = $true)] [string] $BackupDirectory, [switch] $EnableException ) Invoke-TimeSignal -Start $Params = @{DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd; TrustedConnection = $TrustedConnection; } $sqlCommand = Get-SQLCommand @Params $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\backuprestoredb.sql") -join [Environment]::NewLine $null = $sqlCommand.Parameters.Add("@CurrentDatabase", $DatabaseName) $null = $sqlCommand.Parameters.Add("@NewName", $NewDatabaseName) $null = $sqlCommand.Parameters.Add("@BackupDirectory", $BackupDirectory) try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $null = $sqlCommand.ExecuteNonQuery() $true } catch { $messageString = "Something went wrong while doing backup / restore against the database." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ return } finally { $sqlCommand.Connection.Close() $sqlCommand.Dispose() } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/internal/functions/invoke-sqlpackage.ps1 ================================================  <# .SYNOPSIS Invoke the sqlpackage executable .DESCRIPTION Invoke the sqlpackage executable and pass the necessary parameters to it .PARAMETER Action Can either be import or export .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER TrustedConnection Should the sqlpackage work with TrustedConnection or not .PARAMETER FilePath Path to the file, used for either import or export .PARAMETER Properties Array of all the properties that needs to be parsed to the sqlpackage.exe .PARAMETER DiagnosticFile Path to where you want the SqlPackage to output a diagnostics file to assist you in troubleshooting .PARAMETER ModelFile Path to the model file that you want the SqlPackage.exe to use instead the one being part of the bacpac file This is used to override SQL Server options, like collation and etc .PARAMETER MaxParallelism Sets SqlPackage.exe's degree of parallelism for concurrent operations running against a database The default value is 8 .PARAMETER PublishFile Path to the profile / publish xml file that contains all the advanced configuration instructions for the SqlPackage Used only in combination with the Publish action .PARAMETER LogPath The path where the log file(s) will be saved .PARAMETER ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output .PARAMETER OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> $BaseParams = @{ DatabaseServer = $DatabaseServer DatabaseName = $DatabaseName SqlUser = $SqlUser SqlPwd = $SqlPwd } PS C:\> $ImportParams = @{ Action = "import" FilePath = $BacpacFile } PS C:\> Invoke-SqlPackage @BaseParams @ImportParams This will start the sqlpackage.exe file and pass all the needed parameters. .NOTES Author: Mötz Jensen (@splaxi) #> function Invoke-SqlPackage { [CmdletBinding()] [OutputType([System.Boolean])] param ( [ValidateSet("Import", "Export", "Publish")] [string] $Action, [string] $DatabaseServer, [string] $DatabaseName, [string] $SqlUser, [string] $SqlPwd, [string] $TrustedConnection, [string] $FilePath, [string[]] $Properties, [string] $DiagnosticFile, [string] $ModelFile, [int] $MaxParallelism, [Alias("ProfileFile")] [string] $PublishFile, [string] $LogPath, [switch] $ShowOriginalProgress, [switch] $OutputCommandOnly, [switch] $EnableException ) $executable = $Script:SqlPackagePath Invoke-TimeSignal -Start if (!(Test-PathExists -Path $executable -Type Leaf)){ try{ $envSqlPackage = (Get-Command -Name "sqlpackage.exe").Source if (!(Test-PathExists -Path $envSqlPackage -Type Leaf)) { return } else{ $executable = $envSqlPackage Set-D365SqlPackagePath -Path $executable } } catch { # SqlPackage.exe is not in $Script:SqlPackagePath # and not in %PATH%, so return } } Write-PSFMessage -Level Verbose -Message "Starting to prepare the parameters for sqlpackage.exe" [System.Collections.ArrayList]$Params = New-Object -TypeName "System.Collections.ArrayList" if ($Action -eq "export") { $null = $Params.Add("/Action:export") $null = $Params.Add("/SourceServerName:$DatabaseServer") $null = $Params.Add("/SourceDatabaseName:$DatabaseName") $null = $Params.Add("/SourceTrustServerCertificate:True") $null = $Params.Add("/TargetFile:`"$FilePath`"") $null = $Params.Add("/Properties:CommandTimeout=0") if (!$UseTrustedConnection) { $null = $Params.Add("/SourceUser:$SqlUser") $null = $Params.Add("/SourcePassword:$SqlPwd") } Remove-Item -Path $FilePath -ErrorAction SilentlyContinue -Force } elseif ($Action -eq "import") { $null = $Params.Add("/Action:import") $null = $Params.Add("/TargetServerName:$DatabaseServer") $null = $Params.Add("/TargetDatabaseName:$DatabaseName") $null = $Params.Add("/TargetTrustServerCertificate:True") $null = $Params.Add("/SourceFile:`"$FilePath`"") $null = $Params.Add("/Properties:CommandTimeout=0") if (!$UseTrustedConnection) { $null = $Params.Add("/TargetUser:$SqlUser") $null = $Params.Add("/TargetPassword:$SqlPwd") } } elseif ($Action -eq "publish") { $Params.Add("/Action:Publish") > $null $Params.Add("/TargetServerName:$DatabaseServer") > $null $Params.Add("/TargetDatabaseName:$DatabaseName") > $null $Params.Add("/TargetTrustServerCertificate:True") > $null $Params.Add("/SourceFile:`"$FilePath`"") > $null $Params.Add("/Properties:CommandTimeout=0") > $null if (-not $UseTrustedConnection) { $Params.Add("/TargetUser:$SqlUser") > $null $Params.Add("/TargetPassword:$SqlPwd") > $null } if ($PublishFile) { $Params.Add("/Profile:`"$PublishFile`"") > $null } } foreach ($item in $Properties) { $Params.Add("/Properties:$item") > $null } if ($DiagnosticFile) { $Params.Add("/Diagnostics:true") > $null $Params.Add("/DiagnosticsFile:`"$DiagnosticFile`"") > $null } if ($ModelFile) { $Params.Add("/ModelFilePath:`"$ModelFile`"") > $null } if ($MaxParallelism) { $Params.Add("/MaxParallelism:$MaxParallelism") > $null } $result = Invoke-Process -Path $executable -Params "/Version" $version = $result.stdout -replace "`r`n", "" Write-PSFMessage -Level Verbose -Message "Using SQLPackage version $version" Invoke-Process -Executable $executable -Params $params -ShowOriginalProgress:$ShowOriginalProgress -OutputCommandOnly:$OutputCommandOnly -LogPath $LogPath if (Test-PSFFunctionInterrupt) { Write-PSFMessage -Level Critical -Message "The SqlPackage.exe exited with an error." Stop-PSFFunction -Message "Stopping because of errors." -StepsUpward 1 return } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/internal/functions/invoke-timesignal.ps1 ================================================  <# .SYNOPSIS Handle time measurement .DESCRIPTION Handle time measurement from when a cmdlet / function starts and ends Will write the output to the verbose stream (Write-PSFMessage -Level Verbose) .PARAMETER Start Switch to instruct the cmdlet that a start time registration needs to take place .PARAMETER End Switch to instruct the cmdlet that a time registration has come to its end and it needs to do the calculation .EXAMPLE PS C:\> Invoke-TimeSignal -Start This will start the time measurement for any given cmdlet / function .EXAMPLE PS C:\> Invoke-TimeSignal -End This will end the time measurement for any given cmdlet / function. The output will go into the verbose stream. .NOTES Author: Mötz Jensen (@Splaxi) #> function Invoke-TimeSignal { [CmdletBinding(DefaultParameterSetName = 'Start')] param ( [Parameter(Mandatory = $true, ParameterSetName = 'Start', Position = 1 )] [switch] $Start, [Parameter(Mandatory = $True, ParameterSetName = 'End', Position = 2 )] [switch] $End ) $Time = (Get-Date) $Command = (Get-PSCallStack)[1].Command if ($Start) { if ($Script:TimeSignals.ContainsKey($Command)) { 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." $Script:TimeSignals[$Command] = $Time } else { $Script:TimeSignals.Add($Command, $Time) } } else { if ($Script:TimeSignals.ContainsKey($Command)) { $TimeSpan = New-TimeSpan -End $Time -Start (($Script:TimeSignals)[$Command]) Write-PSFMessage -Level Verbose -Message "Total time spent inside the function was $TimeSpan" -Target $TimeSpan -FunctionName $Command -Tag "TimeSignal" $null = $Script:TimeSignals.Remove($Command) } else { Write-PSFMessage -Level Verbose -Message "The command '$Command' was never started to take part in time measurement." } } } ================================================ FILE: d365fo.tools/internal/functions/new-d365foaadapplication.ps1 ================================================  <# .SYNOPSIS Creates a new Azure Active Directory (AAD) application .DESCRIPTION Creates a new Azure Active Directory (AAD) application in a Dynamics 365 for Finance & Operations instance .PARAMETER sqlCommand The SQL Command object that should be used when creating the new application .PARAMETER Name The name that the imported application should have inside the D365FO environment .PARAMETER UserId The id of the user linked to the application inside the D365FO environment .PARAMETER ClientId The Client ID that the imported application should use inside the D365FO environment .EXAMPLE PS C:\> $SqlCommand = Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" PS C:\> New-D365FOAadApplication -SqlCommand $SqlCommand -Name "Application1" -UserId "admin" -ClientId "aef2e67c-64a3-4c72-9294-d288c5bf503d" This will get a SqlCommand object that will connect to the localhost server and the AXDB database, with the sql credential "User123". 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. .NOTES Author: Gert Van Der Heyden (@gertvdheyden) #> function New-D365FOAadApplication { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] Param ( [System.Data.SqlClient.SqlCommand] $SqlCommand, [string] $Name, [string] $UserId, [string] $ClientId ) $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\Add-AadApplicationIntoD365FO.sql") -join [Environment]::NewLine Write-PSFMessage -Level Verbose -Message "Adding Application : $Name,$UserId,$ClientId" $null = $sqlCommand.Parameters.Add("@Name", $Name) $null = $sqlCommand.Parameters.Add("@UserId", $UserId) $null = $sqlCommand.Parameters.Add("@ClientId", $ClientId) Write-PSFMessage -Level Verbose -Message "Creating the application in database" Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $null = $sqlCommand.ExecuteNonQuery() Write-PSFMessage -Level Verbose -Message "Added application" } ================================================ FILE: d365fo.tools/internal/functions/new-d365fouser.ps1 ================================================  <# .SYNOPSIS Creates a new user .DESCRIPTION Creates a new user in a Dynamics 365 for Finance & Operations instance .PARAMETER sqlCommand The SQL Command object that should be used when creating the new user .PARAMETER SignInName The sign in name (email address) for the user that you want the SID from .PARAMETER Name The name that the imported user should have inside the D365FO environment .PARAMETER Id The ID that the imported user should have inside the D365FO environment .PARAMETER SID The SID that correlates to the imported user inside the D365FO environment .PARAMETER StartUpCompany The default company (legal entity) for the imported user .PARAMETER IdentityProvider The provider for the imported to validated against .PARAMETER NetworkDomain The network domain of the imported user .PARAMETER ObjectId The Azure Active Directory object id for the imported user .PARAMETER Language Language that should be configured for the user, for when they sign-in to the D365 environment .EXAMPLE PS C:\> $SqlCommand = Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" 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" This will get a SqlCommand object that will connect to the localhost server and the AXDB databae, with the sql credential "User123". 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. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function New-D365FOUser { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] Param ( [System.Data.SqlClient.SqlCommand] $SqlCommand, [string] $SignInName, [string] $Name, [string] $Id, [string] $SID, [string] $StartUpCompany, [string] $IdentityProvider, [string] $NetworkDomain, [string] $ObjectId, [string] $Language ) $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\Add-AadUserIntoD365FO.sql") -join [Environment]::NewLine Write-PSFMessage -Level Verbose -Message "Adding User : $SignInName,$Name,$Id,$SID,$StartUpCompany,$IdentityProvider,$NetworkDomain" $null = $sqlCommand.Parameters.Add("@SignInName", $SignInName) $null = $sqlCommand.Parameters.Add("@Name", $Name) $null = $sqlCommand.Parameters.Add("@SID", $SID) $null = $sqlCommand.Parameters.Add("@NetworkDomain", $NetworkDomain) $null = $sqlCommand.Parameters.Add("@IdentityProvider", $IdentityProvider) $null = $sqlCommand.Parameters.Add("@StartUpCompany", $StartUpCompany) $null = $sqlCommand.Parameters.Add("@Id", $Id) $null = $sqlCommand.Parameters.Add("@ObjectId", $ObjectId) $null = $sqlCommand.Parameters.Add("@Language", $Language) Write-PSFMessage -Level Verbose -Message "Creating the user in database" Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $rowsCreated = $sqlCommand.ExecuteScalar() Write-PSFMessage -Level Verbose -Message "Rows inserted $rowsCreated for user $SignInName" $SqlCommand.Parameters.Clear() $rowsCreated -eq 1 } ================================================ FILE: d365fo.tools/internal/functions/new-d365selfsignedcertificate.ps1 ================================================  <# .SYNOPSIS Create a new self signed certificate .DESCRIPTION Create a new self signed certificate and have it password protected .PARAMETER CertificateFileName Path to the location where you want to store the CER file for the certificate .PARAMETER PrivateKeyFileName Path to the location where you want to store the PFX file for the certificate .PARAMETER Password The password that you want to use to protect your different certificates with .EXAMPLE 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) This will generate a new CER certificate that is stored at "C:\temp\d365fo.tools\TestAuth.cer". This will generate a new PFX certificate that is stored at "C:\temp\d365fo.tools\TestAuth.pfx". Both certificates will be password protected with "pass@word1". .NOTES Author: Kenny Saelen (@kennysaelen) Author: Mötz Jensen (@Splaxi) #> function New-D365SelfSignedCertificate { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 1)] [string] $CertificateFileName = (Join-Path $env:TEMP "TestAuthCert.cer"), [Parameter(Mandatory = $false, Position = 2)] [string] $PrivateKeyFileName = (Join-Path $env:TEMP "TestAuthCert.pfx"), [Parameter(Mandatory = $false, Position = 3)] [Security.SecureString] $Password = (ConvertTo-SecureString -String "Password1" -Force -AsPlainText) ) try { # First generate a self-signed certificate and place it in the local store on the machine $certificate = New-SelfSignedCertificate -dnsname 127.0.0.1 -CertStoreLocation cert:\LocalMachine\My -FriendlyName "D365 Automated testing certificate" -Provider "Microsoft Strong Cryptographic Provider" $certificatePath = 'cert:\localMachine\my\' + $certificate.Thumbprint # Export the private key Export-PfxCertificate -cert $certificatePath -FilePath $PrivateKeyFileName -Password $Password # Import the certificate into the local machine's trusted root certificates store $importedCertificate = Import-PfxCertificate -FilePath $PrivateKeyFileName -CertStoreLocation Cert:\LocalMachine\Root -Password $Password } catch { 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 Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } return $importedCertificate } ================================================ FILE: d365fo.tools/internal/functions/new-decryptedfile.ps1 ================================================  <# .SYNOPSIS Decrypt web.config file .DESCRIPTION Utilize the built in encryptor utility to decrypt the web.config file from inside the AOS .PARAMETER File Path to the file that you want to work against Please be careful not to point to the original file from inside the AOS directory .PARAMETER DropPath Path to the directory where you want save the file after decryption is completed .EXAMPLE PS C:\> New-DecryptedFile -File "C:\temp\d365fo.tools\web.config" -DropPath "c:\temp\d365fo.tools\decrypted.config" This will take the "C:\temp\d365fo.tools\web.config" and decrypt it. After decryption the output file will be stored in "c:\temp\d365fo.tools\decrypted.config". .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function New-DecryptedFile { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] Param ( [string] $File, [string] $DropPath ) $Decrypter = Join-Path $AosServiceWebRootPath -ChildPath "bin\Microsoft.Dynamics.AX.Framework.ConfigEncryptor.exe" if (-not (Test-PathExists -Path $Decrypter -Type Leaf)) { return } $fileInfo = [System.IO.FileInfo]::new($File) $DropFile = Join-Path $DropPath $FileInfo.Name Write-PSFMessage -Level Verbose -Message "Extracted file path is: $DropFile" -Target $DropFile Copy-Item $File $DropFile -Force -ErrorAction Stop if (-not (Test-PathExists -Path $DropFile -Type Leaf)) { return } & $Decrypter -decrypt $DropFile } ================================================ FILE: d365fo.tools/internal/functions/new-webrequest.ps1 ================================================  <# .SYNOPSIS Get a web request object .DESCRIPTION Get a prepared web request object with all necessary headers and tokens in place .PARAMETER RequestUrl The URL you want to work against .PARAMETER AuthorizationHeader The Authorization Header object that you want to use for you web request .PARAMETER Action The HTTP action you want to preform .EXAMPLE PS C:\> New-WebRequest -RequestUrl "https://login.windows.net/contoso/.well-known/openid-configuration" -AuthorizationHeader $null -Action GET This will create a new web request object that will work against the "https://login.windows.net/contoso/.well-known/openid-configuration" URL. The HTTP action is GET and in this case we don't need an Authorization Header in place. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function New-WebRequest { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] param ( $RequestUrl, $AuthorizationHeader, $Action ) Write-PSFMessage -Level Verbose -Message "New Request $RequestUrl, $Action" $request = [System.Net.WebRequest]::Create($RequestUrl) if ($null -ne $AuthorizationHeader) { $request.Headers["Authorization"] = $AuthorizationHeader.CreateAuthorizationHeader() } $request.Method = $Action $request } ================================================ FILE: d365fo.tools/internal/functions/publish-d365foresources.ps1 ================================================  <# .SYNOPSIS Publish resources .DESCRIPTION Publishes Dynamics 365 for Finance and Operations resources to the publishing directory. .PARAMETER ResourceTypes The types of resources to publish. .PARAMETER PublishingDirectory The directory to publish the resources to. Each resource type will be published to a subdirectory. .PARAMETER PackageDirectory The directory containing the resources. .PARAMETER AosServiceWebRootPath The path to the AOS service web root containing the metadata assemblies to access the resources. .EXAMPLE PS C:\> Publish-D365FOResources -ResourceTypes Images,Scripts,Styles,Html -PublishingDirectory C:\temp\resources This will publish the resources of the types Images, Scripts, Styles, and Html to the directory C:\temp\resources. .NOTES Author: Florian Hopfner (@FH-Inway) #> function Publish-D365FOResources { [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', 'Publish-D365FOResources')] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [string[]] $ResourceTypes, [Parameter(Mandatory = $true)] [string] $PublishingDirectory, [Parameter(Mandatory = $false)] [PsfDirectory] $PackageDirectory = $Script:PackageDirectory, [Parameter(Mandatory = $false)] [PsfDirectory] $AosServiceWebRootPath = $Script:AOSPath ) Invoke-TimeSignal -Start Write-PSFMessage -Level Verbose -Message "Initializing resources publishing." $resourcesDirectory = $PublishingDirectory foreach ($resourceType in $ResourceTypes) { $resourceTypeDirectory = Join-Path $resourcesDirectory $resourceType Test-PathExists -Path $resourceTypeDirectory -Type Container -Create | Out-Null } Import-Assemblies -AosServiceWebRootPath $AosServiceWebRootPath # For unknown reasons, the provider cannot be initialized in a separate function. # If this is done, $metadataProviderViaRuntime.Resources is null. Write-PSFMessage -Level Debug -Message "Initializing metadata runtime provider." $runtimeProviderConfiguration = New-Object Microsoft.Dynamics.AX.Metadata.Storage.Runtime.RuntimeProviderConfiguration -ArgumentList $PackageDirectory $metadataProviderFactoryViaRuntime = New-Object Microsoft.Dynamics.AX.Metadata.Storage.MetadataProviderFactory $metadataProviderViaRuntime = $metadataProviderFactoryViaRuntime.CreateRuntimeProvider($runtimeProviderConfiguration) Write-PSFMessage -Level Verbose -Message "Starting resources publishing" $resources = $metadataProviderViaRuntime.Resources.GetPrimaryKeys() foreach ($resourceItem in $resources) { $params = @{ ResourceItem = $resourceItem MetadataProviderViaRuntime = $metadataProviderViaRuntime ResourceTypes = $ResourceTypes ResourcesDirectory = $resourcesDirectory } Publish-Resource @params } Write-PSFMessage -Level Host -Message "Resources publishing completed." Invoke-TimeSignal -End } function Import-Assemblies { [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', 'Import-Assemblies')] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [PsfDirectory] $AosServiceWebRootPath ) Write-PSFMessage -Level Debug -Message "Importing required assemblies." [System.Collections.ArrayList] $Files2Process = New-Object -TypeName "System.Collections.ArrayList" $binDir = Join-Path $AosServiceWebRootPath "bin" $null = $Files2Process.Add((Join-Path $binDir Microsoft.Dynamics.AX.Metadata.Core.dll)) $null = $Files2Process.Add((Join-Path $binDir Microsoft.Dynamics.AX.Metadata.dll)) $null = $Files2Process.Add((Join-Path $binDir Microsoft.Dynamics.AX.Metadata.Storage.dll)) $null = $Files2Process.Add((Join-Path $binDir Microsoft.Dynamics.Performance.Instrumentation.dll)) $null = $Files2Process.Add((Join-Path $binDir Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.dll)) Import-AssemblyFileIntoMemory -Path $($Files2Process.ToArray()) } function Publish-Resource { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [object] $ResourceItem, [Parameter(Mandatory = $true)] [object] $MetadataProviderViaRuntime, [Parameter(Mandatory = $true)] [string[]] $ResourceTypes, [Parameter(Mandatory = $true)] [string] $ResourcesDirectory ) $resourceName = [System.String]$ResourceItem Write-PSFMessage -Level Debug -Message "Processing resource '$resourceName'." $resourceHeader = New-Object -TypeName Microsoft.Dynamics.AX.Metadata.MetaModel.MetaReadHeader $resource = $MetadataProviderViaRuntime.Resources.Read($resourceName, [ref]$resourceHeader) $resourceTimestamp = $MetadataProviderViaRuntime.Resources.GetContentTimestampUtc($resource, $resourceHeader) $resourceType = $resource.TypeOfResource $resourcePath = Join-Path $ResourcesDirectory $resourceType $resourceFilePath = Join-Path $resourcePath $resource.FileName Write-PSFMessage -Level Debug -Message "Checking resource '$resourceName' of type '$resourceType' for publishing." $resourceData = @{ ResourceType = $resourceType ResourceName = $resourceName ResourceTimestamp = $resourceTimestamp } $params = @{ ResourceData = $resourceData AllowedResourceTypes = $ResourceTypes ResourceFilePath = $resourceFilePath } $shouldPublishResource = Test-PublishResource @params if (-not $shouldPublishResource) { Write-PSFMessage -Level Debug -Message "Resource '$resourceName' is not being published." continue } Write-PSFMessage -Level Debug -Message "Publishing resource '$resourceName' to '$resourceFilePath'." $sourceStream = $MetadataProviderViaRuntime.Resources.GetContent($resource, $resourceHeader) if ($sourceStream) { $argumentList = @( $resourceFilePath, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write ) $targetStream = New-Object -TypeName System.IO.FileStream -ArgumentList $argumentList $sourceStream.CopyTo($targetStream) $sourceStream.Close() $targetStream.Close() Write-PSFMessage -Level Debug -Message "Resource '$resourceName' published successfully." } } function Test-PublishResource { [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [hashtable] $ResourceData, [Parameter(Mandatory = $true)] [string[]] $AllowedResourceTypes, [Parameter(Mandatory = $true)] [string] $ResourceFilePath ) $resourceType = $ResourceData.ResourceType $resourceName = $ResourceData.ResourceName $resourceTimestamp = $ResourceData.ResourceTimestamp $isAResourceTypeToPublish = $AllowedResourceTypes -contains $resourceType if (-not $isAResourceTypeToPublish) { Write-PSFMessage -Level Debug -Message "Resource '$resourceName' of type '$resourceType' is not a resource type to publish. Skipping." return $false } if (-not (Test-PathExists -Path $ResourceFilePath -Type Leaf -WarningAction SilentlyContinue -ErrorAction SilentlyContinue)) { Write-PSFMessage -Level Debug -Message "Resource '$resourceName' does not exist. Will be published." return $true } $existingFileTimestamp = (Get-ItemProperty $resourceFilePath).LastWriteTimeUtc if ($existingFileTimestamp -ne $ResourceTimestamp) { Write-PSFMessage -Level Debug -Message "Resource '$ResourceName' is outdated (resource time stamp: $ResouceTimestamp, existing file time stamp: $existingFileTimestamp). Will be published." return $true } Write-PSFMessage -Level Debug -Message "Resource '$ResourceName' is up to date." return $false } ================================================ FILE: d365fo.tools/internal/functions/readme.md ================================================ # Functions This is the folder where the internal functions go. Depending on the complexity of the module, it is recommended to subdivide them into subfolders. The module will pick up all .ps1 files recursively ================================================ FILE: d365fo.tools/internal/functions/remove-lcsassetfile.ps1 ================================================  <# .SYNOPSIS Delete a single asset from the LCS project Asset Library .DESCRIPTION Delete a single asset from the LCS project Asset Library .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER AssetId Id of the asset you want to delete .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts Usually this parameter is not used directly, but via the Enable-D365Exception cmdlet See https://github.com/d365collaborative/d365fo.tools/wiki/Exception-handling#what-does-the--enableexception-parameter-do for further information .EXAMPLE Remove-LcsAssetFile -ProjectId 123456789 -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" -AssetId "812bcb0e-23fb-476d-8a92-985f20a704b9" This will delete the Asset file from the LCS Asset Library. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .NOTES Tags: Environment, LCS, Api, AAD, Token, Asset, File, Files Author: Oleksandr Nikolaiev (@onikolaiev) #> function Remove-LcsAssetFile { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Cmdletbinding()] param( [Parameter(Mandatory = $true)] [int] $ProjectId, [Parameter(Mandatory = $true)] [string] $AssetId, [Alias('Token')] [string] $BearerToken, [Parameter(Mandatory = $true)] [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "POST" $parms.Uri = "$LcsApiUri/box/fileasset/DeleteFileAsset/$($ProjectId)?assetId=$($AssetId)" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms Write-PSFMessage -Level Verbose -Message "Asset was deleted successfully." } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in request for delete asset from the asset library of LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/rename-configvalue.ps1 ================================================  <# .SYNOPSIS Rename the value in the web.config file .DESCRIPTION Replace the old value with the new value inside a web.config file .PARAMETER File Path to the file that you want to update/rename/replace .PARAMETER NewValue The new value that replaces the old value .PARAMETER OldValue The old value that needs to be replaced .EXAMPLE PS C:\> Rename-ConfigValue -File "C:\temp\d365fo.tools\web.config" -NewValue "Demo-8.1" -OldValue "usnconeboxax1aos" This will open the "C:\temp\d365fo.tools\web.config" file and replace all "usnconeboxax1aos" entries with "Demo-8.1" .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Rename-ConfigValue { param ( [string] $File, [string] $NewValue, [string] $OldValue ) Write-PSFMessage -Level Verbose -Message "Replace content from $File. Old value is $OldValue. New value is $NewValue." -Target (@($File, $OldValue, $NewValue)) (Get-Content $File).replace($OldValue, $NewValue) | Set-Content $File } ================================================ FILE: d365fo.tools/internal/functions/repair-bacpacmodelqualifier.ps1 ================================================  <# .SYNOPSIS Repair a bacpac model file - using qualification logic .DESCRIPTION Will use a search pattern, qualification and end pattern, to remove an element from the model file .PARAMETER Path Path to the bacpac model file that you want to work against .PARAMETER OutputPath Path to where the repaired model file should be placed .PARAMETER Search Search pattern that is used to start the removable of the element Supports wildcard - as it utilizes the -Like operation that is available directly in powershell E.g. "**" .PARAMETER Qualifier Qualifier pattern that is used to qualify the element, based on a nested line value Supports wildcard - as it utilizes the -Like operation that is available directly in powershell E.g. "**" .EXAMPLE PS C:\> Repair-BacpacModelQualifier -Path c:\temp\model.xml -OutputPath c:\temp\repaired_model.xml -Search '**' -Qualifier "**" This will remove the below section from the model file .NOTES Author: Mötz Jensen (@Splaxi) 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. This cmdlet is inspired by the work of "Brad Bateman" (github: @batetech) His github profile can be found here: https://github.com/batetech Florian Hopfner did a gist implementation, which has been used as the foundation for this implementation The original gist is: https://gist.github.com/FH-Inway/f485c720b43b72bffaca5fb6c094707e His github profile can be found here: https://github.com/FH-Inway #> function Repair-BacpacModelQualifier { [CmdletBinding()] param ( [string] $Path, [string] $OutputPath, [string] $Search, [string] $Qualifier, [string] $End ) Invoke-TimeSignal -Start Write-PSFMessage -Level Verbose -Message "Will search for: $Search - Qualify with: $Qualifier" -Target @($Search, $Qualifier, $End) [int]$flushCounter = 500000 $buffer = [System.Collections.Generic.List[string]]::new($flushCounter) #much faster than PS array using += $bufferCounter = 0; try { $stream = [System.IO.StreamReader]::new($Path) :LineLoop while ($stream.Peek() -ge 0) { $line = $stream.ReadLine() # Skipping empty lines if (-not [string]::IsNullOrEmpty($line)) { if ($line -like $Search) { # We hit search pattern, will read lines until hitting the end pattern. # Will buffer all lines going forward, in case we need to keep them in the output file $bufTemp = [System.Collections.Generic.List[string]]::new(20) $bufTemp.Add($line) $foundQualifier = $false while ($stream.Peek() -ge 0) { $line = $stream.ReadLine(); $bufTemp.Add($line) if ($line -like $Qualifier) { $foundQualifier = $true } if ($line -like $End) { if (-not $foundQualifier) { # This tells us to keep all the lines that we buffered $buffer.AddRange($bufTemp.ToArray()) } continue LineLoop } } } # Persisting all lines that didn't meet the search pattern $buffer.Add($line) } else { $buffer.Add($line) } $bufferCounter++; if ($bufferCounter -ge $flushCounter) { $buffer | Add-Content -LiteralPath $OutputPath -Encoding UTF8 $buffer = [System.Collections.Generic.List[string]]::new($flushCounter); $bufferCounter = 0; } } } finally { # We need to close the stream object, to release the file system lock on the input file $stream.Close() $stream.Dispose() } #flush anything still remaining in the buffer if ($bufferCounter -gt 0) { $buffer | Add-Content -LiteralPath $OutputPath -Encoding UTF8 $buffer = $null; $bufferCounter = 0; } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/internal/functions/repair-bacpacmodelsimpleandreplace.ps1 ================================================  <# .SYNOPSIS Repair a bacpac model file - using simple remove AND replace logic .DESCRIPTION Will use a search pattern, and end pattern, to remove an element from the model file Will use a search pattern, with the replacement value, to replace the string within the model file .PARAMETER Path Path to the bacpac model file that you want to work against .PARAMETER OutputPath Path to where the repaired model file should be placed .PARAMETER RemoveInstructions Search pattern that is used to start the removable of the element Supports wildcard - as it utilizes the -Like operation that is available directly in powershell E.g. "**" .PARAMETER ReplaceInstructions Search pattern that is used to replace the value Works directly on the value entered, no wildcard or regex is supported at all E.g. "" Replace value that you want to substitute your search value with E.g. "" .EXAMPLE PS C:\> $removeIns1 = [pscustomobject][ordered]@{Search = '* $replace1 = [pscustomobject][ordered]@{Search = '';Replace = ''} PS C:\> Repair-BacpacModelSimpleAndReplace -Path c:\temp\model.xml -OutputPath c:\temp\repaired_model.xml -RemoveInstructions @($removeIns1) -ReplaceInstructions @($replace1) This will remove the below section from the model file, based on the RemoveInstructions: This will remove the below section from the model file, based on the ReplaceInstructions: .NOTES Author: Mötz Jensen (@Splaxi) 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. This cmdlet is inspired by the work of "Brad Bateman" (github: @batetech) His github profile can be found here: https://github.com/batetech Florian Hopfner did a gist implementation, which has been used as the foundation for this implementation The original gist is: https://gist.github.com/FH-Inway/f485c720b43b72bffaca5fb6c094707e His github profile can be found here: https://github.com/FH-Inway https://devblog.pekspro.com/posts/multiple-find-and-replace-with-powershell #> function Repair-BacpacModelSimpleAndReplace { [CmdletBinding()] param ( [string] $Path, [string] $OutputPath, [Object[]] $RemoveInstructions, [Object[]] $ReplaceInstructions ) Invoke-TimeSignal -Start Write-PSFMessage -Level Verbose -Message "RemoveInstructions count is: $($RemoveInstructions.Count)" -Target $RemoveInstructions Write-PSFMessage -Level Verbose -Message "ReplaceInstructions count is: $($ReplaceInstructions.Count)" -Target $ReplaceInstructions [int]$flushCounter = 500000 $buffer = [System.Collections.Generic.List[string]]::new($flushCounter) #much faster than PS array using += $bufferCounter = 0; try { $stream = [System.IO.StreamReader]::new($Path) :LineLoop while ($stream.Peek() -ge 0) { $line = $stream.ReadLine() # Skipping empty lines if (-not [string]::IsNullOrEmpty($line)) { # Implement Replace Logic directly here - so we only handle replace once, if the line contains data.. foreach ($ReplaceIns in $ReplaceInstructions) { $line = $line.Replace($ReplaceIns.Search, $ReplaceIns.Replace) } foreach ($remove in $RemoveInstructions) { if ($line -like $remove.Search) { # We found the search pattern - next is just removing lines, until we find the end pattern while ($stream.Peek() -ge 0) { $line = $stream.ReadLine(); if ($line -like $remove.End) { # We found the end tag, so we need to start the line loop again. continue LineLoop } } } } $buffer.Add($line) } else { $buffer.Add($line) } $bufferCounter++; if ($bufferCounter -ge $flushCounter) { $buffer | Add-Content -LiteralPath $OutputPath -Encoding UTF8 $buffer = [System.Collections.Generic.List[string]]::new($flushCounter); $bufferCounter = 0; } } } finally { $stream.Close() $stream.Dispose() } # Flush anything still remaining in the buffer if ($bufferCounter -gt 0) { $buffer | Add-Content -LiteralPath $OutputPath -Encoding UTF8 $buffer = $null; $bufferCounter = 0; } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/internal/functions/select-defaultview.ps1 ================================================  <# .SYNOPSIS Short description .DESCRIPTION Long description .PARAMETER InputObject Parameter description .PARAMETER Property Parameter description .PARAMETER ExcludeProperty Parameter description .PARAMETER TypeName Parameter description .EXAMPLE PS C:\> Select-DefaultView -InputObject $result -Property CommandName, Synopsis This will help you do it right. .NOTES Author: Mötz Jensen (@Splaxi) #> function Select-DefaultView { <# This command enables us to send full on objects to the pipeline without the user seeing it a lot of this is from boe, thanks boe! https://learn-powershell.net/2013/08/03/quick-hits-set-the-default-property-display-in-powershell-on-custom-objects/ TypeName creates a new type so that we can use ps1xml to modify the output #> [CmdletBinding()] param ( [parameter(ValueFromPipeline)] [object] $InputObject, [string[]] $Property, [string[]] $ExcludeProperty, [string] $TypeName ) process { if ($null -eq $InputObject) { return } if ($TypeName) { $InputObject.PSObject.TypeNames.Insert(0, "d365fo.tools.$TypeName") } if ($ExcludeProperty) { if ($InputObject.GetType().Name.ToString() -eq 'DataRow') { $ExcludeProperty += 'Item', 'RowError', 'RowState', 'Table', 'ItemArray', 'HasErrors' } $props = ($InputObject | Get-Member | Where-Object MemberType -in 'Property', 'NoteProperty', 'AliasProperty' | Where-Object { $_.Name -notin $ExcludeProperty }).Name $defaultset = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet', [string[]]$props) } else { # property needs to be string if ("$property" -like "* as *") { $newproperty = @() foreach ($p in $property) { if ($p -like "* as *") { $old, $new = $p -isplit " as " # Do not be tempted to not pipe here $inputobject | Add-Member -Force -MemberType AliasProperty -Name $new -Value $old -ErrorAction SilentlyContinue $newproperty += $new } else { $newproperty += $p } } $property = $newproperty } $defaultset = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet', [string[]]$Property) } $standardmembers = [System.Management.Automation.PSMemberInfo[]]@($defaultset) # Do not be tempted to not pipe here $inputobject | Add-Member -Force -MemberType MemberSet -Name PSStandardMembers -Value $standardmembers -ErrorAction SilentlyContinue $inputobject } } ================================================ FILE: d365fo.tools/internal/functions/set-adminuser.ps1 ================================================  <# .SYNOPSIS Provision an user to be the administrator of a Dynamics 365 for Finance & Operations environment .DESCRIPTION Provision an user to be the administrator by using the supplied tools from Microsoft (AdminUserProvisioning.exe) .PARAMETER SignInName The sign in name (email address) for the user that you want to be the administrator .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Set-AdminUser -SignInName "Claire@contoso.com" -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" This will provision the user with the e-mail "Claire@contoso.com" to be the administrator of the D365 for Finance & Operations instance. It will handle if the tenant is switching also, and update the necessary details. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) Author: Mark Furrer (@devax_mf) #> function Set-AdminUser { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] Param ( [string] $SignInName, [string] $DatabaseServer, [string] $DatabaseName, [string] $SqlUser, [string] $SqlPwd, [switch] $EnableException ) $WebConfigFile = Join-Path $Script:AOSPath $Script:WebConfig $MetaDataNode = Select-Xml -XPath "/configuration/appSettings/add[@key='Aos.MetadataDirectory']/@value" -Path $WebConfigFile $MetaDataNodeDirectory = $MetaDataNode.Node.Value Write-PSFMessage -Level Verbose -Message "MetaDataDirectory: $MetaDataNodeDirectory" -Target $MetaDataNodeDirectory $AdminFileLocationPu29AndUp = "$MetaDataNodeDirectory\Bin\Microsoft.Dynamics.AdminUserProvisioningLib.dll" $AdminFileLocationBeforePu29 = "$MetaDataNodeDirectory\Bin\AdminUserProvisioning.exe" if ( Test-Path -Path $AdminFileLocationPu29AndUp -PathType Leaf ) { $AdminFile = $AdminFileLocationPu29AndUp $AdminLibNameSpace = "Microsoft.Dynamics.AdminUserProvisioningLib" } else { $AdminFile = $AdminFileLocationBeforePu29 $AdminLibNameSpace = "Microsoft.Dynamics.AdminUserProvisioning" } Write-PSFMessage -Level Verbose -Message "Path to AdminFile: $AdminFile" $TempFileName = New-TemporaryFile $TempFileName = $TempFileName.BaseName $AdminDll = "$env:TEMP\$TempFileName.dll" copy-item -Path $AdminFile -Destination $AdminDll $adminAssembly = [System.Reflection.Assembly]::LoadFile($AdminDll) $AdminUserUpdater = $adminAssembly.GetType("$AdminLibNameSpace.AdminUserUpdater") $PublicBinding = [System.Reflection.BindingFlags]::Public $StaticBinding = [System.Reflection.BindingFlags]::Static $CombinedBinding = $PublicBinding -bor $StaticBinding $UpdateAdminUser = $AdminUserUpdater.GetMethod("UpdateAdminUser", $CombinedBinding) Write-PSFMessage -Level Verbose -Message "Adjusting parameter set to the PU that is in use in this environment." if((($UpdateAdminUser.GetParameters()).Name) -contains "hostUrl") { Write-PSFMessage -Level Verbose -Message "PU29 or higher found. Will adjust parameters." $params = $SignInName, "AAD-Global", $null, $null, $DatabaseServer, $DatabaseName, $SqlUser, $SqlPwd, "$Script:AOSPath\", $Script:Url } elseif((($UpdateAdminUser.GetParameters()).Name) -contains "providerName") { Write-PSFMessage -Level Verbose -Message "PU26/27/28 found. Will adjust parameters." $params = $SignInName, "AAD-Global", $null, $null, $DatabaseServer, $DatabaseName, $SqlUser, $SqlPwd } else { Write-PSFMessage -Level Verbose -Message "PU below PU26 found. Will adjust parameters." $params = $SignInName, $null, $null, $DatabaseServer, $DatabaseName, $SqlUser, $SqlPwd } try { $paramsString = $params -join ", " Write-PSFMessage -Level Verbose -Message "Updating Admin using the values $paramsString" $UpdateAdminUser.Invoke($null, $params) } catch { $messageString = "Something went wrong while provisioning the environment to the new administrator: $SignInName." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target $SignInName Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ -StepsUpward 1 return } } ================================================ FILE: d365fo.tools/internal/functions/set-azurebacpacvalues.ps1 ================================================  <# .SYNOPSIS Change the different Azure SQL Database details .DESCRIPTION When preparing an Azure SQL Database to be the new database for an Tier 2+ environment you need to set different details .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER AxDeployExtUserPwd Password obtained from LCS .PARAMETER AxDbAdminPwd Password obtained from LCS .PARAMETER AxRuntimeUserPwd Password obtained from LCS .PARAMETER AxMrRuntimeUserPwd Password obtained from LCS .PARAMETER AxRetailRuntimeUserPwd Password obtained from LCS .PARAMETER AxRetailDataSyncUserPwd Password obtained from LCS .PARAMETER AxDbReadonlyUserPwd Password obtained from LCS .PARAMETER TenantId The ID of tenant that the Azure SQL Database instance is going to be run under .PARAMETER PlanId The ID of the type of plan that the Azure SQL Database is going to be using .PARAMETER PlanCapability The capabilities that the Azure SQL Database instance will be running with .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE 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" This will set all the needed details inside the "Import" database that is located in the "dbserver1.database.windows.net" Azure SQL Database instance. All service accounts and their passwords will be updated accordingly. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Set-AzureBacpacValues { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [string] $DatabaseServer, [Parameter(Mandatory = $true)] [string] $DatabaseName, [Parameter(Mandatory = $true)] [string] $SqlUser, [Parameter(Mandatory = $true)] [string] $SqlPwd, [Parameter(Mandatory = $true)] [string] $AxDeployExtUserPwd, [Parameter(Mandatory = $true)] [string] $AxDbAdminPwd, [Parameter(Mandatory = $true)] [string] $AxRuntimeUserPwd, [Parameter(Mandatory = $true)] [string] $AxMrRuntimeUserPwd, [Parameter(Mandatory = $true)] [string] $AxRetailRuntimeUserPwd, [Parameter(Mandatory = $true)] [string] $AxRetailDataSyncUserPwd, [Parameter(Mandatory = $true)] [string] $AxDbReadonlyUserPwd, [Parameter(Mandatory = $true)] [string] $TenantId, [Parameter(Mandatory = $true)] [string] $PlanId, [Parameter(Mandatory = $true)] [string] $PlanCapability, [switch] $EnableException ) $sqlCommand = Get-SQLCommand -DatabaseServer $DatabaseServer -DatabaseName $DatabaseName -SqlUser $SqlUser -SqlPwd $SqlPwd -TrustedConnection $false $commandText = (Get-Content "$script:ModuleRoot\internal\sql\set-bacpacvaluesazure.sql") -join [Environment]::NewLine $commandText = $commandText.Replace('@axdeployextuser', $AxDeployExtUserPwd) $commandText = $commandText.Replace('@axdbadmin', $AxDbAdminPwd) $commandText = $commandText.Replace('@axruntimeuser', $AxRuntimeUserPwd) $commandText = $commandText.Replace('@axmrruntimeuser', $AxMrRuntimeUserPwd) $commandText = $commandText.Replace('@axretailruntimeuser', $AxRetailRuntimeUserPwd) $commandText = $commandText.Replace('@axretaildatasyncuser', $AxRetailDataSyncUserPwd) $commandText = $commandText.Replace('@axdbreadonlyuser', $AxDbReadonlyUserPwd) $sqlCommand.CommandText = $commandText $null = $sqlCommand.Parameters.Add("@TenantId", $TenantId) $null = $sqlCommand.Parameters.Add("@PlanId", $PlanId) $null = $sqlCommand.Parameters.Add("@PlanCapability ", $PlanCapability) try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $null = $sqlCommand.ExecuteNonQuery() $true } catch { $messageString = "Something went wrong while working against the database." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } } ================================================ FILE: d365fo.tools/internal/functions/set-browserbookmark.ps1 ================================================  <# .SYNOPSIS Set a new bookmark in the browser .DESCRIPTION Add a new bookmark to the favorite bar in the browser Edge and Chrome behaves the same .PARAMETER PathBrowser Path to the root folder of the profile in the browser Only default is tested / handled .PARAMETER Uri Uri of the system that you want to add as a bookmark .PARAMETER Name Name of the bookmark entry .EXAMPLE 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" This will work against the Edge browser. The bookmark will be for the 'https://devdevaos.axcloud.dynamics.com/?cmp=DAT&mi=DefaultDashboard' system. The name will be "D365FO". .NOTES Author: Mötz Jensen (@Splaxi) #> function Set-BrowserBookmark { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] param ( [string] $PathBrowser, [string] $Uri, [string] $Name ) $pathBase = "$PathBrowser" if ((Test-PathExists -Path $pathBase -Type Container)) { $prefRaw = Get-Content -Path "$pathBase\Preferences" -Raw $prefObj = $prefRaw | ConvertFrom-Json if ($null -eq $prefObj.bookmark_bar) { # Sometimes the needed settings is missing $prefRaw.Replace(',"browser":', ',"bookmark_bar":{"show_on_all_tabs": true,"show_only_on_ntp":false},"browser":') | Out-File -FilePath "$pathBase\Preferences" -Encoding utf8 -Force } else { $prefObj.bookmark_bar.show_on_all_tabs = $true $($prefObj | ConvertTo-Json -Depth 10).Replace("`r`n", "") | Out-File -FilePath "$pathBase\Preferences" -Encoding utf8 -Force > $null } if (-not (Test-PathExists -Path "$pathBase\Bookmarks" -Type Leaf)) { # We might be handling bookmarks / favorites for the first time Copy-Item -Path "$script:ModuleRoot\internal\misc\Bookmarks" -Destination "$pathBase\Bookmarks" -Force > $null } $favRaw = Get-Content -Path "$pathBase\Bookmarks" -Raw $favObj = $favRaw | ConvertFrom-Json # If any bookmarks already exists - we need to up the counter / id $id = [int]$($favObj.roots.bookmark_bar.children.id | Sort-Object -Descending | Select-Object -First 1) $id++ $bookMark = [PsCustomObject][Ordered]@{ guid = [System.Guid]::NewGuid().Guid id = $id name = $name type = "url" url = $URL } # The children property is an array - which is a fixed size $children = [System.Collections.Generic.List[System.Object]]::new($favObj.roots.bookmark_bar.children) $children.Add($bookMark) $favObj.roots.bookmark_bar.children = $children.ToArray() $($favObj | ConvertTo-Json -Depth 10) | Out-File -FilePath "$pathBase\Bookmarks" -Encoding utf8 -Force > $null } } ================================================ FILE: d365fo.tools/internal/functions/set-sqlbacpacvalues.ps1 ================================================  <# .SYNOPSIS Set the SQL Server specific values .DESCRIPTION Set the SQL Server specific values when restoring a bacpac file .PARAMETER DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net .PARAMETER DatabaseName The name of the database .PARAMETER SqlUser The login name for the SQL Server instance .PARAMETER SqlPwd The password for the SQL Server user .PARAMETER TrustedConnection Should the connection use a Trusted Connection or not .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Set-SqlBacpacValues -DatabaseServer localhost -DatabaseName "AxDB" -SqlUser "User123" -SqlPwd "Password123" This will connect to the "AXDB" database that is available in the SQL Server instance running on the localhost. It will use the "User123" SQL Server credentials to connect to the SQL Server instance. This will set all the necessary SQL Server database options and create the needed objects in side the "AxDB" database. .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Set-SqlBacpacValues { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] [OutputType('System.Boolean')] param ( [Parameter(Mandatory = $true)] [string] $DatabaseServer, [Parameter(Mandatory = $true)] [string] $DatabaseName, [Parameter(Mandatory = $false)] [string] $SqlUser, [Parameter(Mandatory = $false)] [string] $SqlPwd, [Parameter(Mandatory = $false)] [bool] $TrustedConnection, [switch] $EnableException ) $Params = @{DatabaseServer = $DatabaseServer; DatabaseName = $DatabaseName; SqlUser = $SqlUser; SqlPwd = $SqlPwd; TrustedConnection = $TrustedConnection; } # We have learned that pooling keeps the connection open and that is not what we want $sqlCommand = Get-SQLCommand @Params -NoPooling $commandText = (Get-Content "$script:ModuleRoot\internal\sql\set-bacpacvaluessql.sql") -join [Environment]::NewLine $commandText = $commandText.Replace('@DATABASENAME', $DatabaseName) $sqlCommand.CommandText = $commandText try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $sqlCommand.Connection.Open() $sqlCommand.ExecuteNonQuery() $true } catch { $messageString = "Something went wrong while working against the database." Write-PSFMessage -Level Host -Message $messageString -Exception $PSItem.Exception -Target (Get-SqlString $SqlCommand) Stop-PSFFunction -Message "Stopping because of errors." -Exception $([System.Exception]::new($($messageString -replace '<[^>]+>', ''))) -ErrorRecord $_ return } finally { if ($sqlCommand.Connection.State -ne [System.Data.ConnectionState]::Closed) { $sqlCommand.Connection.Close() } $sqlCommand.Dispose() } } ================================================ FILE: d365fo.tools/internal/functions/start-lcsdatabaseexportv2.ps1 ================================================  <# .SYNOPSIS Start a database export from an environment .DESCRIPTION Start a database export from an environment from a LCS project .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER SourceEnvironmentId The unique id of the environment that you want to use as the source for the database export The Id can be located inside the LCS portal .PARAMETER BackupName Name of the backup file when it is being exported from the environment The file shouldn't contain any extension at all, just the desired file name .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Start-LcsDatabaseExportV2 -ProjectId 123456789 -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -BackupName "BackupViaApi" -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will start the database export from the Source environment. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The backup name is identified by the BackupName "BackupViaApi", which instructs the API to save the backup with that filename. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .LINK Get-LcsDatabaseOperationStatus .NOTES Tags: Environment, Config, Configuration, LCS, Database backup, Api, Backup, Bacpac Author: Mötz Jensen (@Splaxi) #> function Start-LcsDatabaseExportV2 { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Cmdletbinding()] param( [Parameter(Mandatory = $true)] [int] $ProjectId, [Parameter(Mandatory = $true)] [Alias('Token')] [string] $BearerToken, [Parameter(Mandatory = $true)] [string] $SourceEnvironmentId, [Parameter(Mandatory = $true)] [string] $BackupName, [Parameter(Mandatory = $true)] [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "POST" $parms.Uri = "$LcsApiUri/databasemovement/v1/export/project/$($ProjectId)/environment/$($SourceEnvironmentId)/backupName/$($BackupName)" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in starting a new database export in LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception -Target $_ Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/start-lcsdatabaserefreshv2.ps1 ================================================  <# .SYNOPSIS Start a database refresh between 2 environments .DESCRIPTION Start a database refresh between 2 environments from a LCS project .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER SourceEnvironmentId The unique id of the environment that you want to use as the source for the database refresh The Id can be located inside the LCS portal .PARAMETER TargetEnvironmentId The unique id of the environment that you want to use as the target for the database refresh The Id can be located inside the LCS portal .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE 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" This will start the database refresh between the Source and Target environments. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The target environment is identified by the TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .LINK Get-LcsDatabaseOperationStatus .NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deployable Package Author: Mötz Jensen (@Splaxi) #> function Start-LcsDatabaseRefreshV2 { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Cmdletbinding()] param( [Parameter(Mandatory = $true)] [int] $ProjectId, [Parameter(Mandatory = $true)] [Alias('Token')] [string] $BearerToken, [Parameter(Mandatory = $true)] [string] $SourceEnvironmentId, [Parameter(Mandatory = $true)] [string] $TargetEnvironmentId, [Parameter(Mandatory = $true)] [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "POST" $parms.Uri = "$LcsApiUri/databasemovement/v1/refresh/project/$($ProjectId)/source/$($SourceEnvironmentId)/target/$($TargetEnvironmentId)" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in starting a new database refresh in LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception -Target $_ Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/start-lcsdeploymentv2.ps1 ================================================  <# .SYNOPSIS Start LCS deployment .DESCRIPTION Start the deployment of a deployable package from the LCS API .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER AssetId The unique id of the asset / file that you are trying to deploy from LCS .PARAMETER EnvironmentId The unique id of the environment that you want to work against The Id can be located inside the LCS portal .PARAMETER UpdateName Name of the update when you are working against Self-Service environments .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE 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" This will start the deployment of the file located in the Asset Library. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. 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. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "Bearer JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). .NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deployable Package Author: Mötz Jensen (@Splaxi) #> function Start-LcsDeploymentV2 { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Cmdletbinding()] param( [Parameter(Mandatory = $true)] [int] $ProjectId, [Parameter(Mandatory = $true)] [Alias('Token')] [string] $BearerToken, [Parameter(Mandatory = $true)] [string] $AssetId, [Parameter(Mandatory = $true)] [string] $EnvironmentId, [Parameter(Mandatory = $false)] [string] $UpdateName, [Parameter(Mandatory = $true)] [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "POST" $parms.Uri = "$LcsApiUri/environment/v2/applyupdate/project/$($ProjectId)/environment/$($EnvironmentId)/asset/$($AssetId)?updateName=$($UpdateName)" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in starting a new deployment in LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception -Target $_ Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/start-lcsenvironmentstartstopv2.ps1 ================================================  <# .SYNOPSIS Start or stop a given environment using LCS .DESCRIPTION Start or stop a specified IAAS environment that is Customer Managed through the LCS API. .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER EnvironmentId The unique id of the environment that you want to take action upon The Id can be located inside the LCS portal .PARAMETER IsStop When set to True, the environment will be stopped. When set to False, the environment will be started. .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE PS C:\> Start-LcsEnvironmentStartStopV2 -ProjectId 123456789 -EnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -IsStop $False -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will trigger the environment start operation upon the given environment through the LCS API. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" .EXAMPLE PS C:\> Start-LcsEnvironmentStartStopV2 -ProjectId 123456789 -EnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -IsStop $True -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" This will trigger the environment stop operation upon the given environment through the LCS API. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" .NOTES Tags: Environment, Stop, Start, LCS, Api, AAD, Token Author: Mötz Jensen (@Splaxi), Billy Richardson (@richardsondev) #> function Start-LcsEnvironmentStartStopV2 { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Cmdletbinding()] param( [Parameter(Mandatory = $true)] [int] $ProjectId, [Parameter(Mandatory = $true)] [Alias('Token')] [string] $BearerToken, [Parameter(Mandatory = $true)] [string] $EnvironmentId, [Parameter(Mandatory = $true)] [boolean] $IsStop, [Parameter(Mandatory = $true)] [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $internalAction = "start"; if ($IsStop -eq $True) { $internalAction = "stop"; } $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "POST" $parms.Uri = "$LcsApiUri/environment/v1/$($internalAction)/project/$($ProjectId)/environment/$($EnvironmentId)" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in starting a new deployment in LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception -Target $_ Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/start-lcsuploadv2.ps1 ================================================  <# .SYNOPSIS Start the upload process to LCS .DESCRIPTION Start the flow of actions to upload a file to LCS .PARAMETER BearerToken The token you want to use when working against the LCS api .PARAMETER ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS .PARAMETER FileType Type of file you want to upload Valid options: "Model" "Process Data Package" "Software Deployable Package" "GER Configuration" "Data Package" "PowerBI Report Model" "E-Commerce Package" "NuGet Package" "Retail Self-Service Package" "Commerce Cloud Scale Unit Extension" .PARAMETER Name Name to be assigned / shown on LCS .PARAMETER Filename Filename to be assigned / shown on LCS Often will it require an extension for it to be accepted .PARAMETER Description Description to be assigned / shown on LCS .PARAMETER LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" .PARAMETER RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint .PARAMETER EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts .EXAMPLE 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" This will contact the NON-EUROPE LCS API and instruct it that we want to upload a new file to the Asset Library. The token "Bearer JldjfafLJdfjlfsalfd..." is used to the authorize against the LCS API. The ProjectId is 123456789 and FileType is "SoftwareDeployablePackage". The file will be named "ReadyForTesting" and the Description will be "Latest release that fixes it all". .NOTES Tags: Url, LCS, Upload, Api, Token Author: Mötz Jensen (@Splaxi) #> function Start-LcsUploadV2 { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Cmdletbinding()] param( [Parameter(Mandatory = $true)] [Alias('Token')] [string] $BearerToken, [Parameter(Mandatory = $true)] [int] $ProjectId, [Parameter(Mandatory = $true)] [LcsAssetFileType] $FileType, [string] $Name, [string] $Filename, [string] $Description, [string] $LcsApiUri, [Timespan] $RetryTimeout = "00:00:00", [switch] $EnableException ) begin { Invoke-TimeSignal -Start $fileTypeValue = [int]$FileType $jsonPayload = @{ Name = $Name FileName = $Filename FileDescription = $Description SizeByte = 0 FileType = $fileTypeValue } | ConvertTo-Json $headers = @{ "Authorization" = "$BearerToken" } $parms = @{} $parms.Method = "POST" $parms.Uri = "$LcsApiUri/box/fileasset/CreateFileAsset/$ProjectId" $parms.Headers = $headers $parms.RetryTimeout = $RetryTimeout $parms.Payload = $jsonPayload $parms.ContentType = "application/json" } process { try { Write-PSFMessage -Level Verbose -Message "Invoke LCS request." Invoke-RequestHandler @parms } catch [System.Net.WebException] { Write-PSFMessage -Level Host -Message "Error status code $($_.exception.response.statuscode) in starting a new deployment in LCS. $($_.exception.response.StatusDescription)." -Exception $PSItem.Exception -Target $_ Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the LCS API." -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } Invoke-TimeSignal -End } } ================================================ FILE: d365fo.tools/internal/functions/test-aaduseridind365fo.ps1 ================================================  <# .SYNOPSIS Test to see if a given user ID exists .DESCRIPTION Test to see if a given user ID exists in the Dynamics 365 for Finance & Operations instance .PARAMETER SqlCommand The SQL Command object that should be used when testing the user ID .PARAMETER Id Id of the user that you want to test exists or not .EXAMPLE PS C:\> $SqlCommand = Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" PS C:\> Test-AadUserIdInD365FO -SqlCommand $SqlCommand -Id "TestUser" This will get a SqlCommand object that will connect to the localhost server and the AXDB database, with the sql credential "User123". It will query the the database for any user with the Id "TestUser". .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Test-AadUserIdInD365FO { param ( [System.Data.SqlClient.SqlCommand] $SqlCommand, [string] $Id ) $commandText = (Get-Content "$script:ModuleRoot\internal\sql\test-aaduseridind365fo.sql") -join [Environment]::NewLine $sqlCommand.CommandText = $commandText $null = $sqlCommand.Parameters.Add("@Id", $Id) Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $NumFound = $sqlCommand.ExecuteScalar() Write-PSFMessage -Level Verbose -Message "Number of user rows found in database $NumFound" -Target $NumFound $SqlCommand.Parameters.Clear() $NumFound -ne 0 } ================================================ FILE: d365fo.tools/internal/functions/test-aaduserind365fo.ps1 ================================================  <# .SYNOPSIS Test to see if a given user already exists .DESCRIPTION Test to see if a given user already exists in the Dynamics 365 for Finance & Operations instance .PARAMETER SqlCommand The SQL Command object that should be used when testing the user .PARAMETER SignInName The sign in name (email address) for the user that you want test .EXAMPLE PS C:\> $SqlCommand = Get-SqlCommand -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" PS C:\> Test-AadUserInD365FO -SqlCommand $SqlCommand -SignInName "Claire@contoso.com" This will get a SqlCommand object that will connect to the localhost server and the AXDB database, with the sql credential "User123". It will query the the database for the user with the e-mail address "Claire@contoso.com". .NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) #> function Test-AadUserInD365FO { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [System.Data.SqlClient.SqlCommand] $SqlCommand, [Parameter(Mandatory = $true)] [string] $SignInName ) $sqlCommand.CommandText = (Get-Content "$script:ModuleRoot\internal\sql\test-aaduserind365fo.sql") -join [Environment]::NewLine $null = $sqlCommand.Parameters.Add("@Email", $SignInName) try { Write-PSFMessage -Level InternalComment -Message "Executing a script against the database." -Target (Get-SqlString $SqlCommand) $NumFound = $sqlCommand.ExecuteScalar() Write-PSFMessage -Level Verbose -Message "Number of user rows found in database $NumFound" -Target $NumFound } catch { Write-PSFMessage -Level Host -Message "Something went wrong while working against the database" -Exception $PSItem.Exception Stop-PSFFunction -Message "Stopping because of errors" -StepsUpward 1 return } finally { $SqlCommand.Parameters.Clear() } $NumFound -ne 0 } ================================================ FILE: d365fo.tools/internal/functions/test-assembliesloaded.ps1 ================================================  <# .SYNOPSIS Test if any D365 assemblies are loaded .DESCRIPTION Test if any D365 assemblies are loaded into memory and will be a blocking issue .EXAMPLE PS C:\> Test-AssembliesLoaded This will test in any D365 specific assemblies are loaded into memory. If is, a Stop-PSFFunction test will state that we should stop execution. .NOTES Author: Mötz Jensen (@Splaxi) #> function Test-AssembliesLoaded { [CmdletBinding()] [OutputType()] param ( ) Invoke-TimeSignal -Start $assembliesLoaded = [System.AppDomain]::CurrentDomain.GetAssemblies() | Where-Object Location -ne $null $assembliesBlocking = $assembliesLoaded.location -match "AOSService|Dynamics|PackagesLocalDirectory" if ($assembliesBlocking.Count -gt 0) { Stop-PSFFunction -Message "Stopping because some assembly (DLL) files seems to be loaded into memory." -StepsUpward 1 return } Invoke-TimeSignal -End } ================================================ FILE: d365fo.tools/internal/functions/test-configstoreagelocation.ps1 ================================================  <# .SYNOPSIS Test accessible to the configuration storage .DESCRIPTION Test if the desired configuration storage is accessible with the current user context .PARAMETER ConfigStorageLocation Parameter used to instruct where to store the configuration objects The default value is "User" and this will store all configuration for the active user Valid options are: "User" "System" "System" will store the configuration so all users can access the configuration objects .EXAMPLE PS C:\> Test-ConfigStorageLocation -ConfigStorageLocation "System" This will test if the current executing user has enough privileges to save to the system wide configuration storage. The system wide configuration storage requires administrator rights. .NOTES Author: Mötz Jensen (@Splaxi) #> function Test-ConfigStorageLocation { [CmdletBinding()] [OutputType('System.String')] param ( [ValidateSet('User', 'System')] [string] $ConfigStorageLocation = "User" ) $configScope = "UserDefault" if ($ConfigStorageLocation -eq "System") { if ($Script:IsAdminRuntime) { $configScope = "SystemDefault" } else { Write-PSFMessage -Level Host -Message "Unable to locate save the configuration objects in the system wide configuration store on the machine. Please start an elevated session and run the cmdlet again." Stop-PSFFunction -Message "Elevated permissions needed. Please start an elevated session and run the cmdlet again." -StepsUpward 1 return } } $configScope } ================================================ FILE: d365fo.tools/internal/functions/test-pathexists.ps1 ================================================  <# .SYNOPSIS Test multiple paths .DESCRIPTION Easy way to test multiple paths for public functions and have the same error handling .PARAMETER Path Array of paths you want to test They have to be the same type, either file/leaf or folder/container .PARAMETER Type Type of path you want to test Either 'Leaf' or 'Container' .PARAMETER Create Instruct the cmdlet to create the directory if it doesn't exist .PARAMETER ShouldNotExist Instruct the cmdlet to return true if the file doesn't exists .EXAMPLE PS C:\> Test-PathExists "c:\temp","c:\temp\dir" -Type Container This will test if the mentioned paths (folders) exists and the current context has enough permission. .NOTES Author: Mötz Jensen (@splaxi) #> function Test-PathExists { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $True)] [AllowEmptyString()] [string[]] $Path, [ValidateSet('Leaf', 'Container')] [Parameter(Mandatory = $True)] [string] $Type, [switch] $Create, [switch] $ShouldNotExist ) $res = $false $arrList = New-Object -TypeName "System.Collections.ArrayList" foreach ($item in $Path) { if ([string]::IsNullOrEmpty($item)) { Stop-PSFFunction -Message "Stopping because path was either null or empty string." -StepsUpward 1 return } Write-PSFMessage -Level Debug -Message "Testing the path: $item" -Target $item $temp = Test-Path -Path $item -Type $Type if ((-not $temp) -and ($Create) -and ($Type -eq "Container")) { Write-PSFMessage -Level Debug -Message "Creating the path: $item" -Target $item $null = New-Item -Path $item -ItemType Directory -Force -ErrorAction Stop $temp = $true } elseif ($ShouldNotExist) { Write-PSFMessage -Level Debug -Message "The should NOT exists: $item" -Target $item } elseif ((-not $temp) -and ($WarningPreference -ne [System.Management.Automation.ActionPreference]::SilentlyContinue)) { Write-PSFMessage -Level Host -Message "The $item path wasn't found. Please ensure the path exists and you have enough permission to access the path." } $null = $arrList.Add($temp) } if ($arrList.Contains($false) -and (-not $ShouldNotExist)) { # The $ErrorActionPreference variable determines the behavior we are after, but the "Stop-PSFFunction -WarningAction" is where we need to put in the value. Stop-PSFFunction -Message "Stopping because of missing paths." -StepsUpward 1 -WarningAction $ErrorActionPreference } elseif ($arrList.Contains($true) -and $ShouldNotExist) { # The $ErrorActionPreference variable determines the behavior we are after, but the "Stop-PSFFunction -WarningAction" is where we need to put in the value. Stop-PSFFunction -Message "Stopping because file exists." -StepsUpward 1 -WarningAction $ErrorActionPreference } else { $res = $true } $res } ================================================ FILE: d365fo.tools/internal/functions/test-registryvalue.ps1 ================================================  <# .SYNOPSIS Test if a given registry key exists or not .DESCRIPTION Test if a given registry key exists in the path specified .PARAMETER Path Path to the registry hive and sub directories you want to work against .PARAMETER Name Name of the registry key that you want to test for .EXAMPLE PS C:\> Test-RegistryValue -Path "HKLM:\SOFTWARE\Microsoft\Dynamics\Deployment\" -Name "InstallationInfoDirectory" This will query the LocalMachine hive and the sub directories "HKLM:\SOFTWARE\Microsoft\Dynamics\Deployment\" for a registry key with the name of "InstallationInfoDirectory". .NOTES Author: Mötz Jensen (@Splaxi) #> Function Test-RegistryValue { [OutputType('System.Boolean')] param( [Parameter(Mandatory = $true)] [string]$Path, [Parameter(Mandatory = $true)] [string]$Name ) if (Test-Path -Path $Path -PathType Any) { $null -ne (Get-ItemProperty $Path).$Name } else { $false } } ================================================ FILE: d365fo.tools/internal/functions/test-trustedconnection.ps1 ================================================  <# .SYNOPSIS Test PSBoundParameters whether or not to support TrustedConnection .DESCRIPTION Test callers PSBoundParameters (HashTable) for details that determines whether or not a SQL Server connection should support TrustedConnection or not .PARAMETER Inputs HashTable ($PSBoundParameters) with the parameters from the callers invocation .EXAMPLE PS C:\> $UseTrustedConnection = Test-TrustedConnection $PSBoundParameters 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. .NOTES Author: Mötz Jensen (@splaxi) #> function Test-TrustedConnection { [CmdletBinding()] [OutputType([System.Boolean])] param ( [HashTable] $Inputs ) if (($Inputs.ContainsKey("ImportModeTier2")) -or ($Inputs.ContainsKey("ExportModeTier2"))){ Write-PSFMessage -Level Verbose -Message "Not capable of using Trusted Connection based on Tier validation." $false } elseif (($Inputs.ContainsKey("SqlUser")) -or ($Inputs.ContainsKey("SqlPwd"))) { Write-PSFMessage -Level Verbose -Message "Not capable of using Trusted Connection based on supplied SQL login details." $false } elseif ($Inputs.ContainsKey("TrustedConnection")) { 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 $Inputs.TrustedConnection } else { Write-PSFMessage -Level Verbose -Message "Capabilities based on the centralized logic in the psm1 file." -Target $Script:CanUseTrustedConnection $Script:CanUseTrustedConnection } } ================================================ FILE: d365fo.tools/internal/functions/update-azurestoragevariables.ps1 ================================================  <# .SYNOPSIS Update the Azure Storage config variables .DESCRIPTION Update the active Azure Storage config variables that the module will use as default values .EXAMPLE PS C:\> Update-AzureStorageVariables This will update the Azure Storage variables. .NOTES Author: Mötz Jensen (@Splaxi) #> function Update-AzureStorageVariables { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] [OutputType()] param ( ) $hashParameters = Get-D365ActiveAzureStorageConfig foreach ($item in $hashParameters.Keys) { $name = "AzureStorage" + (Get-Culture).TextInfo.ToTitleCase($item) Write-PSFMessage -Level Verbose -Message "$name - $($hashParameters[$item])" -Target $hashParameters[$item] Set-Variable -Name $name -Value $hashParameters[$item] -Scope Script } } ================================================ FILE: d365fo.tools/internal/functions/update-broadcastvariables.ps1 ================================================  <# .SYNOPSIS Update the broadcast message config variables .DESCRIPTION Update the active broadcast message config variables that the module will use as default values .EXAMPLE PS C:\> Update-BroadcastVariables This will update the broadcast variables. .NOTES Author: Mötz Jensen (@Splaxi) #> function Update-BroadcastVariables { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] [OutputType()] param ( ) $configName = (Get-PSFConfig -FullName "d365fo.tools.active.broadcast.message.config.name").Value.ToString().ToLower() if (-not ($configName -eq "")) { $hashParameters = Get-D365ActiveBroadcastMessageConfig -OutputAsHashtable foreach ($item in $hashParameters.Keys) { if ($item -eq "name") { continue } $name = "Broadcast" + (Get-Culture).TextInfo.ToTitleCase($item) $valueMessage = $hashParameters[$item] if ($item -like "*client*" -and $valueMessage.Length -gt 20) { $valueMessage = $valueMessage.Substring(0,18) + "[...REDACTED...]" } Write-PSFMessage -Level Verbose -Message "$name - $valueMessage" -Target $valueMessage Set-Variable -Name $name -Value $hashParameters[$item] -Scope Script } } } ================================================ FILE: d365fo.tools/internal/functions/update-lcsapivariables.ps1 ================================================  <# .SYNOPSIS Update the LCS API config variables .DESCRIPTION Update the active LCS API config variables that the module will use as default values .EXAMPLE PS C:\> Update-LcsApiVariables This will update the LCS API variables. .NOTES Author: Mötz Jensen (@Splaxi) #> function Update-LcsApiVariables { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] [OutputType()] param ( ) $hashParameters = Get-D365LcsApiConfig -OutputAsHashtable foreach ($item in $hashParameters.Keys) { $name = "LcsApi" + (Get-Culture).TextInfo.ToTitleCase($item) $valueMessage = $hashParameters[$item] if ($item -like "*client*" -and $valueMessage.Length -gt 20) { $valueMessage = $valueMessage.Substring(0,18) + "[...REDACTED...]" } Write-PSFMessage -Level Verbose -Message "$name - $valueMessage" -Target $valueMessage Set-Variable -Name $name -Value $hashParameters[$item] -Scope Script } } ================================================ FILE: d365fo.tools/internal/functions/update-modulevariables.ps1 ================================================  <# .SYNOPSIS Update module variables .DESCRIPTION Loads configuration variables again, to make sure things are updated based on changed configuration .EXAMPLE PS C:\> Update-ModuleVariables This will update internal variables that the module is dependent on. .NOTES Author: Mötz Jensen (@Splaxi) #> function Update-ModuleVariables { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [CmdletBinding()] [OutputType()] param ( ) Update-PsfConfigVariables $Script:AADOAuthEndpoint = Get-PSFConfigValue -FullName "d365fo.tools.azure.common.oauth.token" } ================================================ FILE: d365fo.tools/internal/functions/update-psfconfigvariables.ps1 ================================================  <# .SYNOPSIS Update the module variables based on the PSF Configuration store .DESCRIPTION Will read the current PSF Configuration store and create local module variables .EXAMPLE PS C:\> Update-PsfConfigVariables This will read all relevant PSF Configuration values and create matching module variables. .NOTES Author: Mötz Jensen (@splaxi) #> function Update-PsfConfigVariables { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] [OutputType()] param () foreach ($config in Get-PSFConfig -FullName "d365fo.tools.path.*") { $item = $config.FullName.Replace("d365fo.tools.path.", "") $name = (Get-Culture).TextInfo.ToTitleCase($item) + "Path" Set-Variable -Name $name -Value $config.Value -Scope Script } } ================================================ FILE: d365fo.tools/internal/functions/update-topologyfile.ps1 ================================================  <# .SYNOPSIS Update the topology file .DESCRIPTION Update the topology file based on the already installed list of services on the machine .PARAMETER Path Path to the folder where the Microsoft.Dynamics.AX.AXInstallationInfo.dll assembly is located Should only contain a path to a folder, not a file .PARAMETER TopologyFile Path to the topology file to update If not specified, the default topology file will be used .PARAMETER IncludeFallbackRetailServiceModels Include fallback retail service models in the topology file This parameter is to support backward compatibility in this scenario: Installing the first update on a local VHD where the information about the installed service models may not be available and where the retail components are installed. More information about this can be found at https://github.com/d365collaborative/d365fo.tools/issues/878 .PARAMETER ForceFallbackServiceModels Force the use of the fallback list of known service model names This parameter supports update scenarios primarily on local VHDs where the information about the installed service models may be incomplete. In such a case, the user receives a warning and a suggestion to use this parameter. .EXAMPLE PS C:\> Update-TopologyFile -Path "c:\temp\UpdatePackageFolder" -TopologyFile "c:\temp\d365fo.tools\DefaultTopologyData.xml" This will update the "c:\temp\d365fo.tools\DefaultTopologyData.xml" file with all the installed services on the machine. .NOTES # Credit http://dev.goshoom.net/en/2016/11/installing-deployable-packages-with-powershell/ Author: Tommy Skaue (@Skaue) Author: Mötz Jensen (@Splaxi) Author: Florian Hopfner (@FH-Inway) #> function Update-TopologyFile { [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")] [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $true)] [string]$Path, [string]$TopologyFile, [switch]$IncludeFallbackRetailServiceModels, [switch]$ForceFallbackServiceModels ) if (-not $TopologyFile) { $topologyFile = Join-Path $Path 'DefaultTopologyData.xml' } Write-PSFMessage -Level Verbose "Updating topology file: $topologyFile" [xml]$xml = Get-Content $topologyFile $machine = $xml.TopologyData.MachineList.Machine $machine.Name = $env:computername $serviceModelList = $xml.SelectSingleNode("//ServiceModelList") $null = $serviceModelList.RemoveAll() $models = Get-InstalledServiceModelNameList -Path $Path $params = @{ InstalledModels = $models TopologyFile = $topologyFile IncludeFallbackRetailServiceModels = $IncludeFallbackRetailServiceModels ForceFallbackServiceModels = $ForceFallbackServiceModels } $models = Repair-InstalledServiceModelIssue @params foreach ($name in $models) { $element = $xml.CreateElement('string') $element.InnerText = $name $serviceModelList.AppendChild($element) } $xml.Save($topologyFile) $true } function Get-InstalledServiceModelNameList { [CmdletBinding()] [OutputType([System.Collections.ArrayList])] param ( [Parameter(Mandatory = $true)] [string]$Path ) Write-PSFMessage -Level Verbose "Getting installed service models" $Files2Process = New-Object -TypeName "System.Collections.ArrayList" $null = $Files2Process.Add((Join-Path $Path 'Microsoft.Dynamics.AX.AXInstallationInfo.dll')) Import-AssemblyFileIntoMemory -Path $($Files2Process.ToArray()) $models = [Microsoft.Dynamics.AX.AXInstallationInfo.AXInstallationInfo]::GetInstalledServiceModel() $installedModelNames = $models | ForEach-Object { $_.Name } $installedModelNames } function Repair-InstalledServiceModelIssue { [CmdletBinding()] [OutputType([System.Collections.ArrayList])] param ( [Parameter(Mandatory = $true)] [string[]]$InstalledModels, [string]$TopologyFile, [switch]$IncludeFallbackRetailServiceModels, [switch]$ForceFallbackServiceModels ) Write-PSFMessage -Level Verbose "Handling installed service model issues" $models = $InstalledModels $useFallbackServiceModels = $false $fallbackServiceModels = $Script:FallbackInstallationCoreServiceModelNames if ($null -eq $installedModels -or $installedModels.Count -eq 0) { Write-PSFMessage -Level Warning "No installed service models found." $useFallbackServiceModels = $true } # Compare models and fallback list of known service model names $fallbackModelsNotInInstalledList = $fallbackServiceModels | Where-Object { $_ -notin $models } if ($fallbackModelsNotInInstalledList.Count -gt 0) { 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 ', ')" if ($ForceFallbackServiceModels) { $useFallbackServiceModels = $true } else { Write-PSFMessage -Level Output "If you want to use the fallback list, please use the -ForceFallbackServiceModels switch." } } if ($useFallbackServiceModels) { Write-PSFMessage -Level Output "Using fallback list of known service model names." $serviceModelNames = $fallbackServiceModels if ($IncludeFallbackRetailServiceModels) { $serviceModelNames += $Script:FallbackInstallationRetailServiceModelNames } else { 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." } $models = $serviceModelNames } $models } ================================================ FILE: d365fo.tools/internal/misc/AzureDevOps.url ================================================ [DEFAULT] BASEURL=##URL## [{000214A0-0000-0000-C000-000000000046}] Prop3=19,11 [InternetShortcut] IDList= URL=##URL## IconFile=https://cdn.vsassets.io/content/icons/favicon.ico IconIndex=1 ================================================ FILE: d365fo.tools/internal/misc/Bookmarks ================================================ { "checksum": "a38a604289a5cdc83c5a0397d18a310e", "roots": { "bookmark_bar": { "children": [], "guid": "0bc5d13f-2cba-5d74-951f-3f233fe6c908", "id": "1", "name": "Favourites bar", "source": "unknown", "type": "folder" }, "other": { "children": [], "guid": "82b081ec-3dd3-529c-8475-ab6c344590dd", "id": "2", "name": "Other favourites", "source": "unknown", "type": "folder" }, "synced": { "children": [], "guid": "4cf2e351-0e85-532b-bb37-df045d8f8d0f", "id": "3", "name": "Mobile favourites", "source": "unknown", "type": "folder" } }, "version": 1 } ================================================ FILE: d365fo.tools/internal/misc/D365FO.url ================================================ [DEFAULT] BASEURL=##URL## [{000214A0-0000-0000-C000-000000000046}] Prop3=19,11 [InternetShortcut] IDList= URL=##URL## IconFile=https://lcs.dynamics.com/content/ux/images/365/finops/favicon.ico IconIndex=1 ================================================ FILE: d365fo.tools/internal/misc/RepairBacpac.Qualifier.json ================================================ [ { "Search": "**", "Qualifier": "**" }, { "Search": "**", "Qualifier": "**" } ] ================================================ FILE: d365fo.tools/internal/misc/RepairBacpac.Replace.json ================================================ [ { "Search": "", "Replace": "" }, { "Search": "", "Replace": "" } ] ================================================ FILE: d365fo.tools/internal/misc/RepairBacpac.Simple.json ================================================ [ { "Search": "**" }, { "Search": "**" }, { "Search": "**" } ] ================================================ FILE: d365fo.tools/internal/scripts/enums.ps1 ================================================ enum EnvironmentType { Unknown LocalHostedTier1 AzureHostedTier1 MSHostedTier1 MSHostedTier2 } enum ServerRole { Unknown Development Demo Build AOS BI } enum LcsAssetFileType { Model = 1 ProcessDataPackage = 4 SoftwareDeployablePackage = 10 GERConfiguration = 12 DataPackage = 15 PowerBIReportModel = 19 ECommercePackage = 26 NuGetPackage = 27 RetailSelfServicePackage = 28 CommerceCloudScaleUnitExtension = 29 } ================================================ FILE: d365fo.tools/internal/scripts/license.ps1 ================================================ 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 @" Copyright (c) 2018 Motz Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. "@ ================================================ FILE: d365fo.tools/internal/scripts/load-dotnet-assemblies.ps1 ================================================ # Add the System.Web type Add-Type -AssemblyName System.Web # Add the System.Net.Http type Add-Type -AssemblyName System.Net.Http # Add the System.IO.Compression type Add-Type -AssemblyName System.IO.Compression # Add the System.IO.Compression.FileSystem type Add-Type -AssemblyName System.IO.Compression.FileSystem ================================================ FILE: d365fo.tools/internal/scripts/postimport.ps1 ================================================ # Add all things you want to run after importing the main code # Load Configurations foreach ($file in (Get-ChildItem "$ModuleRoot\internal\configurations\*.ps1" -ErrorAction Ignore)) { . Import-ModuleFile -Path $file.FullName } # Load Tab Expansion foreach ($file in (Get-ChildItem "$ModuleRoot\internal\tepp\*.tepp.ps1" -ErrorAction Ignore)) { . Import-ModuleFile -Path $file.FullName } # Load Tab Expansion Assignment . Import-ModuleFile -Path "$ModuleRoot\internal\tepp\assignment.ps1" # Load License . Import-ModuleFile -Path "$ModuleRoot\internal\scripts\license.ps1" # Load Variables . Import-ModuleFile -Path "$ModuleRoot\internal\scripts\variables.ps1" # Load dot net assemblies . Import-ModuleFile -Path "$ModuleRoot\internal\scripts\load-dotnet-assemblies.ps1" ================================================ FILE: d365fo.tools/internal/scripts/preimport.ps1 ================================================ # Add all things you want to run before importing the main code # Load Enums . Import-ModuleFile -Path "$ModuleRoot\internal\scripts\enums.ps1" ================================================ FILE: d365fo.tools/internal/scripts/variables.ps1 ================================================ $Script:TimeSignals = @{ } Write-PSFMessage -Level Verbose -Message "Gathering all variables to assist the different cmdlets to function" $serviceDrive = ($env:ServiceDrive) -replace " ", "" # When a local Tier1 machine is domain joined, the domain users will not have the %ServiceDrive% environment variable if ([system.string]::IsNullOrEmpty($serviceDrive)) { $serviceDrive = "c:" 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:\" 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):" Write-PSFHostColor -String '[Environment]::SetEnvironmentVariable("ServiceDrive", "C:", "Machine")' } $script:ServiceDrive = $serviceDrive $Script:IsAdminRuntime = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) $Script:WebConfig = "web.config" $Script:DevConfig = "DynamicsDevConfig.xml" $Script:WifConfig = "wif.config" $Script:WifServicesConfig = "wif.services.config" $Script:Hosts = 'C:\Windows\System32\drivers\etc\hosts' $Script:DefaultAOSName = 'usnconeboxax1aos' $Script:IISHostFile = 'C:\Windows\System32\inetsrv\Config\applicationHost.config' $Script:MRConfigFile = 'C:\FinancialReporting\Server\ApplicationService\bin\MRServiceHost.settings.config' #Update all module variables Update-ModuleVariables # Environment variables $environment = Get-ApplicationEnvironment $Script:TenantId = $environment.Aad.TenantDomainGUID $aos = $environment.Aos $Script:AOSPath = $aos.AppRoot $Script:PackageDirectory = $aos.PackageDirectory $Script:MetaDataDir = $aos.MetadataDirectory $dataAccess = $environment.DataAccess $Script:DatabaseServer = $dataAccess.DbServer $Script:DatabaseName = $dataAccess.Database $Script:DatabaseUserName = $dataAccess.SqlUser $Script:DatabaseUserPassword = $dataAccess.SqlPwd $common = $environment.Common $Script:BinDir = $common.BinDir $Script:BinDirTools = $common.DevToolsBinDir $Script:IsOnebox = $common.IsOneboxEnvironment $Script:ServerRole = [ServerRole]::Unknown $RoleVaule = $( If ($environment.Monitoring.MARole -eq "" -or $environment.Monitoring.MARole -eq "dev") { "Development" } Else { $environment.Monitoring.MARole } ) if ($null -ne $RoleVaule) { $Script:ServerRole = [ServerRole][Enum]::Parse([type]"ServerRole", $RoleVaule, $true); } $infrastructure = $environment.Infrastructure $Script:EnvironmentType = [EnvironmentType]::Unknown $Script:CanUseTrustedConnection = $false if ($infrastructure.HostName -like "*cloud.onebox.dynamics.com*") { $Script:EnvironmentType = [EnvironmentType]::LocalHostedTier1 $Script:CanUseTrustedConnection = $true } elseif ($infrastructure.HostName -match "(cloudax|axcloud).*dynamics.com") { $Script:EnvironmentType = [EnvironmentType]::AzureHostedTier1 $Script:CanUseTrustedConnection = $true } elseif ($infrastructure.HostName -like "*sandbox.ax.dynamics.com*") { $Script:EnvironmentType = [EnvironmentType]::MSHostedTier1 $Script:CanUseTrustedConnection = $true } elseif ($infrastructure.HostName -like "*sandbox.operations.*dynamics.com*") { $Script:EnvironmentType = [EnvironmentType]::MSHostedTier2 } $Script:Url = $infrastructure.HostUrl $Script:Company = "DAT" $RegSplat = @{ Path = "HKLM:\SOFTWARE\Microsoft\Dynamics\Deployment\" Name = "InstallationInfoDirectory" } $RegValue = $( if (Test-RegistryValue @RegSplat) { Join-Path (Get-ItemPropertyValue @RegSplat) "InstallationRecords" } else { "" } ) $Script:InstallationRecordsDir = $RegValue # On a local VHD, the information about the installed service models may not be available. # As a fallback, this list of known service model names may be used. $Script:FallbackInstallationCoreServiceModelNames = @( "ALMService", "AOSService", "BIService", "DevToolsService", "DIXFService", "MROneBox", "PerfSDK", "ReportingService" ) # Starting with version 10.0.41, Microsoft has released VHD images without the retail components # preinstalled. The retail components are only included in the fallback list if the user # explicitly requests it. $Script:FallbackInstallationRetailServiceModelNames = @( "RetailCloudPos", "RetailHQConfiguration", "RetailSDK", "RetailSelfService", "RetailServer" ) $Script:UserIsAdmin = $env:UserName -like "*admin*" $Script:TfDir = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\" $Script:SQLTools = "C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn" $Script:SSRSTools = "C:\Program Files\Microsoft SQL Server Reporting Services\Shared Tools" $Script:DefaultTempPath = "c:\temp\d365fo.tools" foreach ($item in (Get-PSFConfig -FullName d365fo.tools.active*)) { $nameTemp = $item.FullName -replace "^d365fo.tools.", "" $name = ($nameTemp -Split "\." | ForEach-Object { (Get-Culture).TextInfo.ToTitleCase($_) } ) -Join "" New-Variable -Name $name -Value $item.Value -Scope Script } #Active LCS Upload config extraction Update-LcsApiVariables $maskOutput = @( "AccessToken", "AzureStorageAccessToken", "Token", "BearerToken", "Password", "RefreshToken", "SAS" "AzureStorageSAS" ) #Active broadcast message config extraction Update-BroadcastVariables #Update different PSF Configuration variables values Update-PsfConfigVariables #Active Azure Storage Configuration variables values Update-AzureStorageVariables (Get-Variable -Scope Script) | ForEach-Object { $val = $null if ($maskOutput -contains $($_.Name)) { $val = "The variable was found - [...REDACTED...]" } else { $val = $($_.Value) } Write-PSFMessage -Level Verbose -Message "$($_.Name) - $val" -Target $val -FunctionName "Variables.ps1" } Write-PSFMessage -Level Verbose -Message "Finished outputting all the variable content." ================================================ FILE: d365fo.tools/internal/sql/add-aadapplicationintod365fo.sql ================================================  /*Variable input @Name,@UserId,@ClientId */ INSERT INTO SYSAADCLIENTTABLE (NAME, USERID, AADCLIENTID) VALUES (@Name, @UserId, @ClientId) ================================================ FILE: d365fo.tools/internal/sql/add-aaduserintod365fo.sql ================================================  /*Variable input @Id,@SignInName,@Name,@SID, @StartUpCompany, @NetworkDomain, @IdentityProvider */ DROP TABLE IF EXISTS #TempUser SET Nocount ON; DECLARE @TableId AS int, @RecId AS bigint, @ExistsCompany as int SELECT @ExistsCompany = count(1) FROM [dbo].[DIRPARTYTABLE] join dbo.[PARTITIONS] p on p.RECID = DIRPARTYTABLE.PARTITION where DATAAREA = @StartUpCompany if(@ExistsCompany = 0) set @StartUpCompany ='dat' /* Get Admin to copy */ SELECT top 1 userInfo.* INTO #TempUser FROM userinfo JOIN [PARTITIONS] ON [PARTITIONS].Recid = userinfo.PARTITION WHERE id = 'admin' AND PARTITIONKEY = 'initial' /*Change row to match the new user */ UPDATE #TempUser SET -- [RECID] = @RecId , [ID] = @Id ,[Name] = @Name ,[SID] = @SID ,[COMPANY] = @StartUpCompany ,[NETWORKALIAS] = @SignInName ,RECVERSION = 1 ,[NETWORKDOMAIN] = @NetworkDomain ,[IDENTITYPROVIDER] = @IdentityProvider ,[OBJECTID] = iif(@ObjectId = '',[OBJECTID],@ObjectId) ,[EXTERNALID] = '' ,[LANGUAGE] = iif(@Language = '',[LANGUAGE],@Language) /* Create the user */ INSERT INTO userinfo (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) SELECT 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 FROM #TempUser DROP TABLE #TempUser SET Nocount OFF; select count(1) from userinfo where [RECID] = (SELECT MAX(Recid) FROM dbo.USERINFO) ================================================ FILE: d365fo.tools/internal/sql/add-bacpacdatabase.sql ================================================ Declare @BackupTo as varchar(404) = @BackupDirectory + '\' + @NewName + '.bak' Declare @BackupName as varchar(150) = @NewName + 'Bacpac full database backup' Declare @BackupCommand as varchar(1000) set @BackupCommand = 'BACKUP DATABASE [' + @CurrentDatabase + '] TO DISK = ''' + @BackupTo + ''' WITH NOFORMAT, INIT, NAME = ''' + @BackupName + ''', SKIP, NOREWIND, NOUNLOAD, STATS = 10' exec (@BackupCommand) Declare @MoveCommand as nvarchar(1000) Declare @MoveResult as nvarchar(1000) SELECT @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, '''')' exec sp_executesql @MoveCommand,N'@MoveResult varchar(1000) output',@MoveResult output Declare @RestoreCommand as varchar(4000) set @RestoreCommand = ' RESTORE DATABASE [' + @NewName + '] FROM DISK = ''' + @BackupTo + ''' WITH FILE = 1, ' + @MoveResult + ', NOUNLOAD, STATS = 5' exec (@RestoreCommand) --File should be obsolute ================================================ FILE: d365fo.tools/internal/sql/backuprestoredb.sql ================================================ Declare @BackupTo as varchar(404) = @BackupDirectory + '\' + @NewName + '.bak' Declare @BackupName as varchar(150) = @NewName + 'Bacpac full database backup' Declare @BackupCommand as varchar(1000) set @BackupCommand = 'BACKUP DATABASE [' + @CurrentDatabase + '] TO DISK = ''' + @BackupTo + ''' WITH COPY_ONLY, COMPRESSION, NOFORMAT, INIT, NAME = ''' + @BackupName + ''', SKIP, NOREWIND, NOUNLOAD, STATS = 10' exec (@BackupCommand) Declare @MoveCommand as nvarchar(1000) Declare @MoveResult as nvarchar(1000) SELECT @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, '''')' exec sp_executesql @MoveCommand,N'@MoveResult varchar(1000) output',@MoveResult output Declare @RestoreCommand as varchar(4000) set @RestoreCommand = ' RESTORE DATABASE [' + @NewName + '] FROM DISK = ''' + @BackupTo + ''' WITH FILE = 1, ' + @MoveResult + ', NOUNLOAD, REPLACE, STATS = 5' exec (@RestoreCommand) ================================================ FILE: d365fo.tools/internal/sql/checkfornewazuredb.sql ================================================ 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; ================================================ FILE: d365fo.tools/internal/sql/clear-azurebacpacdatabase.sql ================================================ --Author: Rasmus Andersen (@ITRasmus) --Author: Charles Colombel (@dropshind) --Author: Tommy Skaue (@skaue) --Prepare a database in Azure SQL Database for export to SQL Server. -- Re-assign full text catalogs to [dbo] BEGIN DECLARE @catalogName NVARCHAR(256); DECLARE @sqlStmtTable NVARCHAR(512) DECLARE reassignfulltextcatalogcursor CURSOR FOR SELECT DISTINCT NAME FROM sys.fulltext_catalogs -- Open cursor and disable on all tables returned OPEN reassignfulltextcatalogcursor FETCH next FROM reassignfulltextcatalogcursor INTO @catalogName WHILE @@FETCH_STATUS = 0 BEGIN SET @sqlStmtTable = 'ALTER AUTHORIZATION ON Fulltext Catalog::[' + @catalogName + '] TO [dbo]' EXEC Sp_executesql @sqlStmtTable FETCH next FROM reassignfulltextcatalogcursor INTO @catalogName END CLOSE reassignfulltextcatalogcursor DEALLOCATE reassignfulltextcatalogcursor END --Disable change tracking on tables where it is enabled. DECLARE @SQL VARCHAR(1000) SET quoted_identifier OFF DECLARE changetrackingcursor CURSOR FOR SELECT 'ALTER TABLE [' + t.NAME + '] DISABLE CHANGE_TRACKING' FROM sys.change_tracking_tables ct INNER JOIN sys.tables t ON ct.object_id = t.object_id OPEN changetrackingcursor FETCH changetrackingcursor INTO @SQL WHILE @@Fetch_Status = 0 BEGIN EXEC(@SQL) FETCH changetrackingcursor INTO @SQL END CLOSE changetrackingcursor DEALLOCATE changetrackingcursor --Disable change tracking on the database itself. IF( 1 = (SELECT 1 FROM sys.change_tracking_databases WHERE database_id = Db_id('@NewDatabase')) ) ALTER DATABASE -- SET THE NAME OF YOUR DATABASE BELOW [@NewDatabase] SET change_tracking = OFF -- Ensure users can be dropped by changing ownership of certain schemas DECLARE @SCHEMASQL VARCHAR(1000) SET quoted_identifier OFF DECLARE schemacursor CURSOR FOR SELECT 'ALTER AUTHORIZATION ON SCHEMA::[' + NAME + '] TO [DBO]; ' FROM sys.schemas WHERE sys.schemas.NAME IN ( 'BACKUP', 'SHADOW', 'BatchScheduling' ) OPEN schemacursor FETCH schemacursor INTO @SCHEMASQL WHILE @@FETCH_STATUS = 0 BEGIN EXEC(@SCHEMASQL) FETCH schemacursor INTO @SCHEMASQL END CLOSE schemacursor DEALLOCATE schemacursor --Drop certificates that are tied to database users, which will cause errors when exporting the database --if not dropped because then the corresponding user(s) can't be dropped later in the script. --These certs are created from User options > Account > Electronic signature > "Get certificate" button in D365FO UI DECLARE certcursor CURSOR FOR SELECT 'DROP CERTIFICATE ' + Quotename(c.NAME) + ';' FROM sys.certificates c WHERE c.principal_id IN (SELECT u.uid FROM sys.sysusers u WHERE issqlrole = 0 AND hasdbaccess = 1 AND NAME <> 'dbo'); OPEN certcursor; FETCH certcursor INTO @SQL; WHILE @@Fetch_Status = 0 BEGIN EXEC(@SQL); FETCH certcursor INTO @SQL; END; CLOSE certcursor; DEALLOCATE certcursor; --Remove the database level users from the database --these will be recreated after importing in SQL Server. DECLARE @userSQL VARCHAR(1000) SET quoted_identifier OFF DECLARE usercursor CURSOR FOR SELECT 'DROP USER [' + NAME + ']' FROM sys.sysusers WHERE issqlrole = 0 AND hasdbaccess = 1 AND NAME <> 'dbo' OPEN usercursor FETCH usercursor INTO @userSQL WHILE @@Fetch_Status = 0 BEGIN EXEC(@userSQL) FETCH usercursor INTO @userSQL END CLOSE usercursor DEALLOCATE usercursor --Delete the SYSSQLRESOURCESTATSVIEW view as it has an Azure-specific definition in it. --We will run db synch later to recreate the correct view for SQL Server. IF( 1 = (SELECT 1 FROM sys.views WHERE NAME = 'SYSSQLRESOURCESTATSVIEW') ) DROP VIEW syssqlresourcestatsview --Next, set system parameters ready for being a SQL Server Database. UPDATE sysglobalconfiguration SET value = 'SQLSERVER' WHERE NAME = 'BACKENDDB' UPDATE sysglobalconfiguration SET value = 0 WHERE NAME = 'TEMPTABLEINAXDB' --Clean up the batch server configuration, server sessions, and printers from the previous environment. TRUNCATE TABLE sysserverconfig TRUNCATE TABLE sysserversessions TRUNCATE TABLE syscorpnetprinters TRUNCATE TABLE sysclientsessions TRUNCATE TABLE batchserverconfig TRUNCATE TABLE batchservergroup --Remove records which could lead to accidentally sending an email externally. UPDATE sysemailparameters SET smtprelayservername = '', mailernoninteractive = 'SMTP' --LANE.SWENKA 9/12/18 Forcing SMTP as Exchange provider can still email on refresh --Remove encrypted SMTP Password record(s) TRUNCATE TABLE sysemailsmtppassword; --GO UPDATE logisticselectronicaddress SET locator = '' WHERE locator LIKE '%@%'; --GO TRUNCATE TABLE printmgmtsettings TRUNCATE TABLE printmgmtdocinstance --Set any waiting, executing, ready, or canceling batches to withhold. UPDATE batchjob SET status = 0 WHERE status IN ( 1, 2, 5, 7 ); --GO -- Clear encrypted hardware profile merchand properties UPDATE dbo.retailhardwareprofile SET securemerchantproperties = NULL WHERE securemerchantproperties IS NOT NULL --BELOW code is used to handle FULLTEXT INDEX / FULLTEST STOPLIST. --Provided by Paul Heisterkamp (Twitter - @braul) DECLARE @_SQL NVARCHAR(4000) ------------------------------------------------------------------------------------- -- ALTER FULLTEXT INDEX ON [TableName] SET STOPLIST = SYSTEM' IF Object_id('tempdb..#TMPSETSTOPLIST') IS NOT NULL DROP TABLE #tmpsetstoplist; CREATE TABLE #tmpsetstoplist ( tablename [NVARCHAR] (250) ); DECLARE cur CURSOR FOR SELECT Object_name(sys.fulltext_indexes.object_id) AS TableName FROM sys.fulltext_indexes WHERE stoplist_id != 0 OPEN cur; DECLARE @TableName [NVARCHAR](250); FETCH next FROM cur INTO @TableName; WHILE @@FETCH_STATUS = 0 BEGIN INSERT INTO #tmpsetstoplist (tablename) VALUES (@TableName); FETCH next FROM cur INTO @TableName; END; CLOSE cur; DEALLOCATE cur; DECLARE cur CURSOR FOR SELECT tablename FROM #tmpsetstoplist; OPEN cur; FETCH next FROM cur INTO @TableName; WHILE @@FETCH_STATUS = 0 BEGIN SET @_SQL = N'ALTER FULLTEXT INDEX ON ' + Quotename(@TableName) + ' SET STOPLIST = SYSTEM' PRINT ( @_SQL ) EXEC Sp_executesql @_SQL FETCH next FROM cur INTO @TableName; END; CLOSE cur; DEALLOCATE cur; ------------------------------------------------------------------------------------- -- DROP FULLTEXT STOPLIST [FullTextStopListName]; IF Object_id('tempdb..#DROPFULLTEXTSTOPLIST') IS NOT NULL DROP TABLE #dropfulltextstoplist; CREATE TABLE #dropfulltextstoplist ( stoplistname [NVARCHAR] (250) ); DECLARE cur CURSOR FOR SELECT NAME FROM sys.fulltext_stoplists OPEN cur; DECLARE @StopListName [NVARCHAR](250); FETCH next FROM cur INTO @StopListName; WHILE @@FETCH_STATUS = 0 BEGIN INSERT INTO #dropfulltextstoplist (stoplistname) VALUES (@StopListName); FETCH next FROM cur INTO @StopListName; END; CLOSE cur; DEALLOCATE cur; DECLARE cur CURSOR FOR SELECT stoplistname FROM #dropfulltextstoplist; OPEN cur; FETCH next FROM cur INTO @StopListName; WHILE @@FETCH_STATUS = 0 BEGIN SET @_SQL = N'DROP FULLTEXT STOPLIST ' + Quotename(@StopListName) + ';' PRINT ( @_SQL ) EXEC Sp_executesql @_SQL FETCH next FROM cur INTO @StopListName; END; CLOSE cur; DEALLOCATE cur; ================================================ FILE: d365fo.tools/internal/sql/clear-d365tempdbtables.sql ================================================ --Create a cursor. DECLARE cur CURSOR FOR SELECT O.NAME FROM SYS.OBJECTS AS O WITH (NOLOCK), SYS.SCHEMAS AS S WITH (NOLOCK) WHERE S.NAME = 'DBO' AND S.SCHEMA_ID = O.SCHEMA_ID AND O.TYPE = 'U' AND O.NAME LIKE 'T[0-9]%' and O.create_date < GETDATE() - @Days OPEN cur; DECLARE @TableName [nvarchar](250); -- Fetch first record FETCH NEXT FROM cur INTO @TableName; -- Loop all records WHILE @@FETCH_STATUS = 0 BEGIN DECLARE @_SQL NVARCHAR(4000) SET @_SQL = N'DROP TABLE ' + QUOTENAME(@TableName) PRINT (@_SQL) EXEC SP_EXECUTESQL @_SQL -- Fetch next record FETCH NEXT FROM cur INTO @TableName; END; CLOSE cur; DEALLOCATE cur; ================================================ FILE: d365fo.tools/internal/sql/clear-sqlbacpacdatabase.sql ================================================  update sysglobalconfiguration set value = 'SQLAZURE' where name = 'BACKENDDB' update sysglobalconfiguration set value = 1 where name = 'TEMPTABLEINAXDB' drop procedure if exists XU_DisableEnableNonClusteredIndexes drop procedure if exists SP_ConfigureTablesForChangeTracking drop procedure if exists SP_ConfigureTablesForChangeTracking_V2 IF EXISTS(SELECT name FROM sys.schemas WHERE name = 'NT AUTHORITY\NETWORK SERVICE') BEGIN drop schema [NT AUTHORITY\NETWORK SERVICE] END IF DATABASE_PRINCIPAL_ID('NT AUTHORITY\NETWORK SERVICE') IS NOT NULL BEGIN drop user [NT AUTHORITY\NETWORK SERVICE] END IF DATABASE_PRINCIPAL_ID('axdbadmin') IS NOT NULL BEGIN drop user axdbadmin END IF DATABASE_PRINCIPAL_ID('axdeployuser') IS NOT NULL BEGIN drop user axdeployuser END IF DATABASE_PRINCIPAL_ID('axmrruntimeuser') IS NOT NULL BEGIN drop user axmrruntimeuser END IF DATABASE_PRINCIPAL_ID('axretaildatasyncuser') IS NOT NULL BEGIN drop user axretaildatasyncuser END IF DATABASE_PRINCIPAL_ID('axretailruntimeuser') IS NOT NULL BEGIN drop user axretailruntimeuser END IF DATABASE_PRINCIPAL_ID('axdeployextuser') IS NOT NULL BEGIN drop user axdeployextuser END ; DROP USER IF EXISTS [axdbreadonlyuser]; DISABLE TRIGGER ALL ON dbo.RETAILHARDWAREPROFILE -- Clear encrypted hardware profile merchand properties update dbo.RETAILHARDWAREPROFILE set SECUREMERCHANTPROPERTIES = null where SECUREMERCHANTPROPERTIES is not null ; ENABLE TRIGGER ALL ON dbo.RETAILHARDWAREPROFILE ================================================ FILE: d365fo.tools/internal/sql/disable-changetracking.sql ================================================ USE [@DATABASENAME] --Disable change tracking on tables where it is enabled. DECLARE @SQL VARCHAR(1000) SET QUOTED_IDENTIFIER OFF DECLARE changeTrackingCursor CURSOR FOR SELECT 'ALTER TABLE [' + t.name + '] DISABLE CHANGE_TRACKING' FROM sys.change_tracking_tables ct INNER JOIN sys.tables t ON ct.object_id = t.object_id OPEN changeTrackingCursor FETCH changeTrackingCursor INTO @SQL WHILE @@Fetch_Status = 0 BEGIN EXEC(@SQL) FETCH changeTrackingCursor INTO @SQL END CLOSE changeTrackingCursor DEALLOCATE changeTrackingCursor IF (1 = (SELECT 1 FROM SYS.CHANGE_TRACKING_DATABASES WHERE DATABASE_ID = DB_ID('@DATABASENAME'))) BEGIN ALTER DATABASE [@DATABASENAME] SET CHANGE_TRACKING = OFF END ================================================ FILE: d365fo.tools/internal/sql/disable-flight.sql ================================================ /* Variable input @FlightName,@FlightServiceId */ DECLARE @Enabled AS int, @RecId AS bigint SELECT @Enabled = [ENABLED], @RecId = SYSFLIGHTING.RECID FROM SYSFLIGHTING JOIN [PARTITIONS] ON [PARTITIONS].Recid = SYSFLIGHTING.PARTITION WHERE FLIGHTNAME = @FlightName AND PARTITIONKEY = 'initial' if (@Enabled = 1) UPDATE SYSFLIGHTING SET ENABLED = 0 WHERE RECID = @RecId ================================================ FILE: d365fo.tools/internal/sql/disable-maintenancemode.sql ================================================ --Author: Tommy Skaue (@skaue) UPDATE [SQLSYSTEMVARIABLES] SET [VALUE] = 0 WHERE [PARM] = 'CONFIGURATIONMODE' ================================================ FILE: d365fo.tools/internal/sql/disable-user.sql ================================================ DROP TABLE IF EXISTS #usersdisabled SELECT ID, [NAME], NETWORKALIAS INTO #usersdisabled FROM userinfo where NETWORKALIAS like @Email and [ENABLE] = 1 update userinfo set [ENABLE] = 0,RECVERSION = RECVERSION +1 where NETWORKALIAS like @Email and [ENABLE] = 1 AND [Id] <> 'admin' SELECT ID, [NAME], NETWORKALIAS FROM #usersdisabled DROP TABLE IF EXISTS #usersdisabled ================================================ FILE: d365fo.tools/internal/sql/enable-changetracking.sql ================================================ IF((SELECT 1 FROM SYS.CHANGE_TRACKING_DATABASES WHERE DATABASE_ID = DB_ID('@DATABASENAME')) IS NULL) BEGIN ALTER DATABASE [@DATABASENAME] SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 6 DAYS, AUTO_CLEANUP = ON) END ================================================ FILE: d365fo.tools/internal/sql/enable-flight.sql ================================================ /* Variable input @FlightName,@FlightServiceId */ DECLARE @Enabled AS int, @RecId AS bigint SELECT @Enabled = [ENABLED], @RecId = SYSFLIGHTING.RECID FROM SYSFLIGHTING JOIN [PARTITIONS] ON [PARTITIONS].Recid = SYSFLIGHTING.PARTITION WHERE FLIGHTNAME = @FlightName AND PARTITIONKEY = 'initial' if (@Enabled = 1) return else if (@Enabled = 0) UPDATE SYSFLIGHTING SET ENABLED = 1 WHERE RECID = @RecId else INSERT INTO SYSFLIGHTING (FLIGHTNAME, ENABLED, FLIGHTSERVICEID) VALUES (@FlightName, 1, @FlightServiceId) ================================================ FILE: d365fo.tools/internal/sql/enable-maintenancemode.sql ================================================ --Author: Tommy Skaue (@skaue) UPDATE [SQLSYSTEMVARIABLES] SET [VALUE] = 1 WHERE [PARM] = 'CONFIGURATIONMODE' ================================================ FILE: d365fo.tools/internal/sql/enable-user.sql ================================================ DROP TABLE IF EXISTS #usersenabled SELECT ID, [NAME], NETWORKALIAS INTO #usersenabled FROM userinfo where NETWORKALIAS like @Email and [ENABLE] = 0 update userinfo set [ENABLE] = 1,RECVERSION = RECVERSION +1 where NETWORKALIAS like @Email and [ENABLE] = 0 SELECT ID, [NAME], NETWORKALIAS FROM #usersenabled DROP TABLE IF EXISTS #usersenabled ================================================ FILE: d365fo.tools/internal/sql/get-alltablefields.sql ================================================ SELECT TABLEID AS TableId , FIELDID AS FieldId , Name AS AotName , SQLNAME AS SqlName FROM SQLDICTIONARY WHERE FIELDID <> 0 ORDER BY FIELDID ================================================ FILE: d365fo.tools/internal/sql/get-azureserviceobjective.sql ================================================ SELECT d.name, slo.edition,slo.service_objective FROM sys.databases d JOIN sys.database_service_objectives slo ON d.database_id = slo.database_id ================================================ FILE: d365fo.tools/internal/sql/get-broadcastmessage.sql ================================================ SELECT FROMDATETIME, TODATETIME, AOSID FROM SysBroadcastMessage ORDER BY RECID ================================================ FILE: d365fo.tools/internal/sql/get-broadcastmessageactive.sql ================================================ SELECT FROMDATETIME, TODATETIME, AOSID FROM SysBroadcastMessage WHERE TODATETIME > GETDATE() ORDER BY RECID ================================================ FILE: d365fo.tools/internal/sql/get-database.sql ================================================ SELECT name FROM sys.databases WHERE NAME NOT IN ('master', 'model', 'msdb', 'tempdb') ================================================ FILE: d365fo.tools/internal/sql/get-flight.sql ================================================ /* Variable input */ SELECT SYSFLIGHTING.* FROM SYSFLIGHTING JOIN [PARTITIONS] ON [PARTITIONS].Recid = SYSFLIGHTING.PARTITION WHERE PARTITIONKEY = 'initial' ================================================ FILE: d365fo.tools/internal/sql/get-instancevalues.sql ================================================ select sscs.[VALUE] as TENANTID,pmt.PLANID,pmt.PLANCAPABILITY from [dbo].[SYSSERVICECONFIGURATIONSETTING] sscs join [dbo].PROVISIONINGMESSAGETABLE pmt on 1=1 where sscs.[NAME] = 'TENANTID' ================================================ FILE: d365fo.tools/internal/sql/get-maintenancemode.sql ================================================ SELECT * FROM [SQLSYSTEMVARIABLES] WHERE [PARM] = 'CONFIGURATIONMODE' ================================================ FILE: d365fo.tools/internal/sql/get-tablefields.sql ================================================ SELECT TABLEID AS TableId , FIELDID AS FieldId , Name AS AotName , SQLNAME AS SqlName FROM SQLDICTIONARY WHERE TABLEID = @TableId AND SHADOW = 0 ORDER BY FIELDID ================================================ FILE: d365fo.tools/internal/sql/get-tables.sql ================================================ SELECT TABLEID AS TableId , Name AS AotName , SQLNAME AS SqlName FROM SQLDICTIONARY WHERE FIELDID = 0 ================================================ FILE: d365fo.tools/internal/sql/get-tablesequence.sql ================================================ SELECT --s.object_id AS sequence_object_id, s.name AS sequence_name, SCHEMA_NAME(oParent.schema_id) +'.'+ oParent.name AS table_name, --SCHEMA_NAME(o.schema_id) AS referencing_schema_name, --o.name AS referencing_entity_name, --dep.referencing_id, --dep.referencing_class, --dep.referencing_class_desc, --dep.is_caller_dependent, s.start_value, s.increment, s.minimum_value, s.maximum_value, s.is_cached, s.cache_size, s.current_value FROM sys.objects AS o INNER JOIN sys.sql_expression_dependencies AS dep on dep.referencing_id = o.object_id INNER JOIN sys.sequences AS s ON dep.referenced_id = s.object_id INNER JOIN sys.objects AS oParent ON o.parent_object_id = oParent.object_id WHERE oParent.name LIKE @TableName ================================================ FILE: d365fo.tools/internal/sql/get-tablesinchangedtracking.sql ================================================ USE [@DATABASENAME] SELECT t.name FROM sys.change_tracking_tables ct INNER JOIN sys.tables t ON ct.object_id = t.object_id ORDER BY T.[name] ================================================ FILE: d365fo.tools/internal/sql/get-user.sql ================================================ SELECT ID , [NAME] , NETWORKALIAS , NETWORKDOMAIN , [SID] , IDENTITYPROVIDER , COMPANY , [ENABLE] FROM USERINFO WHERE NETWORKALIAS LIKE @Email ================================================ FILE: d365fo.tools/internal/sql/invoke-sphelp.sql ================================================ exec sp_help '@schema.@table' ================================================ FILE: d365fo.tools/internal/sql/newazuredbfromcopy.sql ================================================ CREATE DATABASE [@NewName] AS COPY OF [@CurrentDatabase] ================================================ FILE: d365fo.tools/internal/sql/remove-database.sql ================================================  DECLARE @kill varchar(8000) = ''; SELECT @kill = @kill + 'KILL ' + CONVERT(varchar(5), c.session_id) + ';' FROM sys.dm_exec_connections AS c JOIN sys.dm_exec_sessions AS s ON c.session_id = s.session_id WHERE db_name(database_id) = '@Database' and c.session_id <> @@SPID exec (@kill) DROP DATABASE [@Database] --File should be obsolute ================================================ FILE: d365fo.tools/internal/sql/remove-user.sql ================================================ DECLARE @Id NVARCHAR(50) SET @Id = (SELECT ID FROM dbo.USERINFO WHERE [NETWORKALIAS] = @Email AND [ID] != 'ADMIN') DELETE dbo.SECURITYUSERROLE WHERE USER_ = @Id DELETE dbo.USERINFO WHERE [NETWORKALIAS] = @Email AND [ID] != 'ADMIN' ================================================ FILE: d365fo.tools/internal/sql/rename-computer.sql ================================================ BEGIN TRY EXEC sp_dropserver @@SERVERNAME; END TRY BEGIN CATCH PRINT 'Old SQL server name could not be dropped!' END CATCH EXEC sp_addserver [@NewComputerName], local; ================================================ FILE: d365fo.tools/internal/sql/set-aadusersecurityind365fo.sql ================================================ /*Variable input @Id */ DROP TABLE IF EXISTS #TempSecurityUserRole DROP TABLE IF EXISTS #TempRecIds BEGIN TRANSACTION SET NOCOUNT ON; DECLARE @TableId AS int ,@RecId AS bigint ,@AdminUserId as NVARCHAR(40) = 'Admin' ,@InitialPartionKey as nvarchar(10) = 'initial' SELECT @Id as USER_, SECURITYUSERROLE.SECURITYROLE, SECURITYUSERROLE.ASSIGNMENTSTATUS, SECURITYUSERROLE.ASSIGNMENTMODE, SECURITYUSERROLE.VALIDFROM, SECURITYUSERROLE.VALIDFROMTZID, SECURITYUSERROLE.VALIDTO, SECURITYUSERROLE.VALIDTOTZID, SECURITYUSERROLE.PARTITION INTO #TempSecurityUserRole FROM SECURITYUSERROLE JOIN [PARTITIONS] ON [PARTITIONS].Recid = SECURITYUSERROLE.PARTITION WHERE [User_] = @AdminUserId AND PARTITIONKEY = @InitialPartionKey INSERT INTO SECURITYUSERROLE ( USER_, SECURITYROLE, ASSIGNMENTSTATUS, ASSIGNMENTMODE, VALIDFROM, VALIDFROMTZID, VALIDTO, VALIDTOTZID, PARTITION ) SELECT * FROM #TempSecurityUserRole DROP TABLE #TempSecurityUserRole /* DROP TABLE #TempRecIds */ commit TRANSACTION Declare @AdminSecurityRoleCount as int SELECT @AdminSecurityRoleCount = count(1) FROM SECURITYUSERROLE JOIN [PARTITIONS] ON [PARTITIONS].Recid = SECURITYUSERROLE.PARTITION WHERE [User_] = @AdminUserId AND PARTITIONKEY = @InitialPartionKey Declare @ImportSecurityRoleCount as int SELECT @ImportSecurityRoleCount = count(1) FROM SECURITYUSERROLE JOIN [PARTITIONS] ON [PARTITIONS].Recid = SECURITYUSERROLE.PARTITION WHERE [User_] = @Id AND PARTITIONKEY = @InitialPartionKey SET Nocount OFF; select @AdminSecurityRoleCount - @ImportSecurityRoleCount ================================================ FILE: d365fo.tools/internal/sql/set-bacpacvaluesazure.sql ================================================ CREATE USER axdeployuser FROM LOGIN axdeployuser EXEC sp_addrolemember 'db_owner', 'axdeployuser' CREATE USER axdeployextuser WITH PASSWORD = '@axdeployextuser' IF EXISTS (select * from sys.database_principals where type = 'R' and name = 'DeployExtensibilityRole') BEGIN EXEC sp_addrolemember 'DeployExtensibilityRole', 'axdeployextuser' END IF EXISTS (select * from sys.database_principals where type = 'R' and name = 'driuser') BEGIN CREATE USER axdbreadonlyuser WITH PASSWORD = '@axdbreadonlyuser' EXEC sp_addrolemember 'driuser', 'axdbreadonlyuser' END CREATE USER axdbadmin WITH PASSWORD = '@axdbadmin' EXEC sp_addrolemember 'db_owner', 'axdbadmin' CREATE USER axruntimeuser WITH PASSWORD = '@axruntimeuser' EXEC sp_addrolemember 'db_datareader', 'axruntimeuser' EXEC sp_addrolemember 'db_datawriter', 'axruntimeuser' CREATE USER axmrruntimeuser WITH PASSWORD = '@axmrruntimeuser' EXEC sp_addrolemember 'ReportingIntegrationUser', 'axmrruntimeuser' EXEC sp_addrolemember 'db_datareader', 'axmrruntimeuser' EXEC sp_addrolemember 'db_datawriter', 'axmrruntimeuser' CREATE USER axretailruntimeuser WITH PASSWORD = '@axretailruntimeuser' EXEC sp_addrolemember 'UsersRole', 'axretailruntimeuser' EXEC sp_addrolemember 'ReportUsersRole', 'axretailruntimeuser' CREATE USER axretaildatasyncuser WITH PASSWORD = '@axretaildatasyncuser' EXEC sp_addrolemember 'DataSyncUsersRole', 'axretaildatasyncuser' ALTER DATABASE SCOPED CONFIGURATION SET MAXDOP=2 ALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION=ON ALTER DATABASE SCOPED CONFIGURATION SET PARAMETER_SNIFFING= ON ALTER DATABASE SCOPED CONFIGURATION SET QUERY_OPTIMIZER_HOTFIXES=OFF Declare @DB as nvarchaR(100) = db_Name(db_id()) Declare @Command as nvarchar(2000) = 'ALTER DATABASE [' + @DB + '] SET COMPATIBILITY_LEVEL = 130;ALTER DATABASE [' + @DB + '] SET QUERY_STORE = ON;' exec (@Command) update [dbo].[SYSSERVICECONFIGURATIONSETTING] set value = @Tenantid where name = 'TENANTID' update dbo.POWERBICONFIG set TENANTID = @Tenantid update dbo.PROVISIONINGMESSAGETABLE set TENANTID = @Tenantid, PLANID = @PlanId, PLANCAPABILITY = @PlanCapability -- Begin Refresh Retail FullText Catalogs DECLARE @RFTXNAME NVARCHAR(MAX); DECLARE @RFTXSQL NVARCHAR(MAX); DECLARE retail_ftx CURSOR FOR SELECT OBJECT_SCHEMA_NAME(object_id) + '.' + OBJECT_NAME(object_id) fullname FROM SYS.FULLTEXT_INDEXES WHERE FULLTEXT_CATALOG_ID = (SELECT TOP 1 FULLTEXT_CATALOG_ID FROM SYS.FULLTEXT_CATALOGS WHERE NAME = 'COMMERCEFULLTEXTCATALOG'); OPEN retail_ftx; FETCH NEXT FROM retail_ftx INTO @RFTXNAME; BEGIN TRY WHILE @@FETCH_STATUS = 0 BEGIN PRINT 'Refreshing Full Text Index ' + @RFTXNAME; EXEC SP_FULLTEXT_TABLE @RFTXNAME, 'activate'; SET @RFTXSQL = 'ALTER FULLTEXT INDEX ON ' + @RFTXNAME + ' START FULL POPULATION'; EXEC SP_EXECUTESQL @RFTXSQL; FETCH NEXT FROM retail_ftx INTO @RFTXNAME; END END TRY BEGIN CATCH PRINT error_message() END CATCH CLOSE retail_ftx; DEALLOCATE retail_ftx; -- End Refresh Retail FullText Catalogs ================================================ FILE: d365fo.tools/internal/sql/set-bacpacvaluessql.sql ================================================ --Author: Rasmus Andersen (@ITRasmus) --Author: Tommy Skaue (@skaue) --Author: Mötz Jensen (@Splaxi) DROP USER IF EXISTS [axretailruntimeuser] DROP USER IF EXISTS [axretaildatasyncuser] DROP USER IF EXISTS [axmrruntimeuser] DROP USER IF EXISTS [axdeployuser] DROP USER IF EXISTS [axdbadmin] DROP USER IF EXISTS [axdeployextuser] DROP USER IF EXISTS [NT AUTHORITY\NETWORK SERVICE] IF EXISTS (SELECT * FROM sys.syslogins WHERE NAME = 'axdeployuser') BEGIN CREATE USER axdeployuser FROM LOGIN axdeployuser EXEC sp_addrolemember 'db_owner', 'axdeployuser' END IF EXISTS (SELECT * FROM sys.syslogins WHERE NAME = 'axdbadmin') BEGIN ALTER AUTHORIZATION ON database::[@DATABASENAME] TO sa CREATE USER axdbadmin FROM LOGIN axdbadmin EXEC sp_addrolemember 'db_owner', 'axdbadmin' END IF EXISTS (SELECT * FROM sys.syslogins WHERE NAME = 'axmrruntimeuser') BEGIN CREATE USER axmrruntimeuser FROM LOGIN axmrruntimeuser EXEC sp_addrolemember 'db_datareader', 'axmrruntimeuser' EXEC sp_addrolemember 'db_datawriter', 'axmrruntimeuser' END IF EXISTS (SELECT * FROM sys.syslogins WHERE NAME = 'axretaildatasyncuser') BEGIN CREATE USER axretaildatasyncuser FROM LOGIN axretaildatasyncuser IF (DATABASE_PRINCIPAL_ID('DataSyncUsersRole') IS NOT NULL) BEGIN EXEC sp_addrolemember 'DataSyncUsersRole', 'axretaildatasyncuser' END END IF EXISTS (SELECT * FROM sys.syslogins WHERE NAME = 'axretailruntimeuser') BEGIN CREATE USER axretailruntimeuser FROM LOGIN axretailruntimeuser IF (DATABASE_PRINCIPAL_ID('UsersRole') IS NOT NULL) BEGIN EXEC sp_addrolemember 'UsersRole', 'axretailruntimeuser' END IF (DATABASE_PRINCIPAL_ID('ReportUsersRole') IS NOT NULL) BEGIN EXEC sp_addrolemember 'ReportUsersRole', 'axretailruntimeuser' END END IF EXISTS (SELECT * FROM sys.syslogins WHERE NAME = 'axdeployextuser') BEGIN CREATE USER axdeployextuser FROM LOGIN axdeployextuser IF (DATABASE_PRINCIPAL_ID('DeployExtensibilityRole') IS NOT NULL) BEGIN EXEC sp_addrolemember 'DeployExtensibilityRole', 'axdeployextuser' END END CREATE USER [NT AUTHORITY\NETWORK SERVICE] FROM LOGIN [NT AUTHORITY\NETWORK SERVICE] EXEC sp_addrolemember 'db_owner', 'NT AUTHORITY\NETWORK SERVICE' UPDATE T1 SET T1.storageproviderid = 0 , T1.accessinformation = '' , T1.modifiedby = 'Admin' , T1.modifieddatetime = getdate() FROM docuvalue T1 WHERE T1.storageproviderid = 1 --Azure storage IF((SELECT 1 FROM SYS.CHANGE_TRACKING_DATABASES WHERE DATABASE_ID = DB_ID('@DATABASENAME')) IS NULL) BEGIN ALTER DATABASE [@DATABASENAME] SET CHANGE_TRACKING = ON (CHANGE_RETENTION = 6 DAYS, AUTO_CLEANUP = ON) END ;--GO DROP PROCEDURE IF EXISTS SP_ConfigureTablesForChangeTracking DROP PROCEDURE IF EXISTS SP_ConfigureTablesForChangeTracking_V2 ;--GO -- Begin Refresh Retail FullText Catalogs DECLARE @RFTXNAME NVARCHAR(MAX); DECLARE @RFTXSQL NVARCHAR(MAX); DECLARE retail_ftx CURSOR FOR SELECT OBJECT_SCHEMA_NAME(object_id) + '.' + OBJECT_NAME(object_id) fullname FROM SYS.FULLTEXT_INDEXES WHERE FULLTEXT_CATALOG_ID = (SELECT TOP 1 FULLTEXT_CATALOG_ID FROM SYS.FULLTEXT_CATALOGS WHERE NAME = 'COMMERCEFULLTEXTCATALOG'); OPEN retail_ftx; FETCH NEXT FROM retail_ftx INTO @RFTXNAME; BEGIN TRY WHILE @@FETCH_STATUS = 0 BEGIN PRINT 'Refreshing Full Text Index ' + @RFTXNAME; EXEC SP_FULLTEXT_TABLE @RFTXNAME, 'activate'; SET @RFTXSQL = 'ALTER FULLTEXT INDEX ON ' + @RFTXNAME + ' START FULL POPULATION'; EXEC SP_EXECUTESQL @RFTXSQL; FETCH NEXT FROM retail_ftx INTO @RFTXNAME; END END TRY BEGIN CATCH PRINT error_message() END CATCH CLOSE retail_ftx; DEALLOCATE retail_ftx; -- End Refresh Retail FullText Catalogs --Next, set system parameters ready for being a SQL Server Database. UPDATE sysglobalconfiguration SET value = 'SQLSERVER' WHERE NAME = 'BACKENDDB' UPDATE sysglobalconfiguration SET value = 0 WHERE NAME = 'TEMPTABLEINAXDB' ================================================ FILE: d365fo.tools/internal/sql/set-sysadmin.sql ================================================ USE [master] CREATE LOGIN [@USER] FROM WINDOWS WITH DEFAULT_DATABASE=[master] ALTER SERVER ROLE [sysadmin] ADD MEMBER [@USER] ================================================ FILE: d365fo.tools/internal/sql/switch-database-tier1.sql ================================================ /* Author: Oleksandr Nikolaiev (@onikolaiev) */ Declare @Command as nvarchar(2000) set @Command =' ALTER DATABASE ['+ @DestinationName + '] SET AUTO_UPDATE_STATISTICS_ASYNC OFF; ALTER DATABASE ['+ @DestinationName + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; ALTER DATABASE ['+ @DestinationName + '] MODIFY NAME = [' + @ToBeName + ']; ALTER DATABASE ['+ @SourceName + '] SET AUTO_UPDATE_STATISTICS_ASYNC OFF; ALTER DATABASE ['+ @SourceName + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; ALTER DATABASE ['+ @SourceName +'] MODIFY NAME = ['+ @DestinationName +']; ALTER DATABASE ['+ @DestinationName + '] SET MULTI_USER; ALTER DATABASE ['+ @DestinationName + '] SET AUTO_UPDATE_STATISTICS_ASYNC ON; ALTER DATABASE ['+ @ToBeName + '] SET MULTI_USER; ALTER DATABASE ['+ @ToBeName + '] SET AUTO_UPDATE_STATISTICS_ASYNC ON; ALTER DATABASE ['+ @DestinationName + '] SET AUTO_CLOSE OFF WITH NO_WAIT ' exec (@Command) ================================================ FILE: d365fo.tools/internal/sql/switch-database-tier2.sql ================================================  Declare @Command as nvarchar(2000) set @Command =' ALTER DATABASE ['+ @DestinationName + '] MODIFY NAME = [' + @ToBeName + ']; ALTER DATABASE ['+ @SourceName +'] MODIFY NAME = ['+ @DestinationName +']; ' exec (@Command) ================================================ FILE: d365fo.tools/internal/sql/test-aaduseridind365fo.sql ================================================ /* Variable input @Id */ select count(1) from USERINFO where [ID] = @Id ================================================ FILE: d365fo.tools/internal/sql/test-aaduserind365fo.sql ================================================ /* Variable input @Email */ select count(1) from USERINFO where NETWORKALIAS = @Email ================================================ FILE: d365fo.tools/internal/sql/update-user.sql ================================================ update userinfo set [sid] = @sid, NETWORKDOMAIN = @networkDomain, IDENTITYPROVIDER = @identityProvider , COMPANY = CASE WHEN @Company IS NULL THEN COMPANY ELSE @Company END where [ID] = @id AND [Id] <> 'admin' ================================================ FILE: d365fo.tools/internal/tepp/assignment.ps1 ================================================ <# # Example: Register-PSFTeppArgumentCompleter -Command Get-Alcohol -Parameter Type -Name d365fo.tools.alcohol #> #File Options Register-PSFTeppArgumentCompleter -Command Invoke-D365LcsUpload -Parameter FileType -Name d365fo.tools.lcs.options Register-PSFTeppArgumentCompleter -Command Get-D365LcsAssetFile -Parameter FileType -Name d365fo.tools.lcs.options #LCS API URLS Register-PSFTeppArgumentCompleter -Command Get-D365LcsApiToken -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls Register-PSFTeppArgumentCompleter -Command Get-D365LcsAssetFile -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls Register-PSFTeppArgumentCompleter -Command Get-D365LcsAssetValidationStatus -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls Register-PSFTeppArgumentCompleter -Command Get-D365LcsDatabaseBackups -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls Register-PSFTeppArgumentCompleter -Command Get-D365LcsDatabaseOperationStatus -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls Register-PSFTeppArgumentCompleter -Command Get-D365LcsDeploymentStatus -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls Register-PSFTeppArgumentCompleter -Command Get-D365LcsEnvironmentHistory -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls Register-PSFTeppArgumentCompleter -Command Get-D365LcsEnvironmentMetadata -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls Register-PSFTeppArgumentCompleter -Command Get-D365LcsSharedAssetFile -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls Register-PSFTeppArgumentCompleter -Command Invoke-D365LcsDatabaseExport -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls Register-PSFTeppArgumentCompleter -Command Invoke-D365LcsDatabaseRefresh -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls Register-PSFTeppArgumentCompleter -Command Invoke-D365LcsDeployment -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls Register-PSFTeppArgumentCompleter -Command Invoke-D365LcsEnvironmentStart -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls Register-PSFTeppArgumentCompleter -Command Invoke-D365LcsEnvironmentStop -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls Register-PSFTeppArgumentCompleter -Command Invoke-D365LcsUpload -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls Register-PSFTeppArgumentCompleter -Command Set-D365LcsApiConfig -Parameter LcsApiUri -Name d365fo.tools.lcs.api.urls #TimeZones Register-PSFTeppArgumentCompleter -Command Send-D365BroadcastMessage -Parameter TimeZone -Name d365fo.tools.timezones Register-PSFTeppArgumentCompleter -Command Add-D365BroadcastMessageConfig -Parameter TimeZone -Name d365fo.tools.timezones #Event Trace Register-PSFTeppArgumentCompleter -Command Start-D365EventTrace -Parameter ProviderName -Name d365fo.tools.event.trace.providers Register-PSFTeppArgumentCompleter -Command Start-D365EventTrace -Parameter OutputFormat -Name d365fo.tools.event.trace.format.options ================================================ FILE: d365fo.tools/internal/tepp/eventtrace.tepp.ps1 ================================================ $scriptBlock = { (Get-NetEventProvider -ShowInstalled | Where-Object name -like "Microsoft-Dynamics*" | Sort-Object Name).Name } Register-PSFTeppScriptblock -Name "d365fo.tools.event.trace.providers" -ScriptBlock $scriptBlock -Mode Simple Register-PSFTeppScriptblock -Name "d365fo.tools.event.trace.format.options" -ScriptBlock { 'bin', 'bincirc', 'csv', 'sql', 'tsv' } ================================================ FILE: d365fo.tools/internal/tepp/example.tepp.ps1 ================================================ <# # Example: Register-PSFTeppScriptblock -Name "d365fo.tools.alcohol" -ScriptBlock { 'Beer','Mead','Whiskey','Wine','Vodka','Rum (3y)', 'Rum (5y)', 'Rum (7y)' } #> ================================================ FILE: d365fo.tools/internal/tepp/lcs.tepp.ps1 ================================================ <# "options": { "1": "Model", "4": "Process Data Package", "10": "Software Deployable Package", "12": "GER Configuration", "15": "Data Package", "19": "PowerBI Report Model" } #> Register-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 } <# [ValidateSet("https://lcsapi.lcs.dynamics.com", "https://lcsapi.eu.lcs.dynamics.com")] #> Register-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' } ================================================ FILE: d365fo.tools/internal/tepp/readme.md ================================================ # Tab Expansion ## Description Modern Tab Expansion was opened to users with the module `Tab Expansion Plus Plus` (TEPP). It 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. The `PSFramework` offers a simplified way of offering just this, as the two example files show. ## Concept Custom tab completion is defined in two steps: - Define a scriptblock that is run when the user hits `TAB` and provides the strings that are his options. - Assign that scriptblock to the parameter of a command. You can assign the same scriptblock multiple times. ## Structure Import order matters. In order to make things work with the default scaffold, follow those rules: - All scriptfiles _defining_ completion scriptblocks like this: `*.tepp.ps1` - Put all your completion assignments in `assignment.ps1` ================================================ FILE: d365fo.tools/internal/tepp/send-d365message.tepp.ps1 ================================================ <# # Example: Register-PSFTeppScriptblock -Name "d365fo.tools.alcohol" -ScriptBlock { 'Beer','Mead','Whiskey','Wine','Vodka','Rum (3y)', 'Rum (5y)', 'Rum (7y)' } #> # Register-PSFTeppScriptblock -Name "d365fo.tools.timezones" -ScriptBlock { [System.TimeZoneInfo]::GetSystemTimeZones().Id } Register-PSFTeppScriptblock -Name "d365fo.tools.timezones" -ScriptBlock { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) [System.TimeZoneInfo]::GetSystemTimeZones() | Where-Object {$PSItem.DisplayName -match $wordToComplete} | ForEach-Object { $CompletionText = '"{0} - [{1}]"' -f $PSItem.DisplayName, $PSItem.StandardName New-Object -TypeName System.Management.Automation.CompletionResult -ArgumentList @($CompletionText) } } ================================================ FILE: d365fo.tools/readme.md ================================================ # PSFModule guidance This is a finished module layout optimized for implementing the PSFramework. If you don't care to deal with the details, this is what you need to do to get started seeing results: - Add the functions you want to publish to `/functions/` - Update the `FunctionsToExport` node in the module manifest (d365fo.tools.psd1). All functions you want to publish should be in a list. - Add internal helper functions the user should not see to `/internal/functions/` ## Path Warning > 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. `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. Content imported through that command thus need not mind the path separator. 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`. ================================================ FILE: d365fo.tools/tests/examples/Get-DeepClone.Tests.ps1 ================================================ $commandName = "Get-DeepClone" $exampleRaw = "PS C:\> Get-DeepClone -InputObject `$HashTable" $HashTable = @{} $example = $exampleRaw -replace "`n.*" -replace "PS C:\\>" Describe "Specific example testing for $commandName" { It "Example - $example" { # mock the tested command so we don't actually do anything # because it can be unsafe and we don't have the environment setup # (so the only thing we are testing is that the code is semantically # correct and provides all the needed params) Mock $commandName { # I am returning true here, # but some of the examples drill down to the returned object # so in strict mode we would fail $true } # here simply invoke the example $result = Invoke-Expression $example # and check that we got result from the mock $result | Should -BeTrue } } ================================================ FILE: d365fo.tools/tests/examples/Import-D365Bacpac.Tests.ps1 ================================================ $commandName = "Import-D365Bacpac" ################################### New Example test ################################### $exampleRaw = "Import-D365Bacpac -ImportModeTier1 -BacpacFile `"C:\temp\uat.bacpac`" -NewDatabaseName `"ImportedDatabase`"" #Remember to escape any variables names in the line above. #Remember to you need to output $true to the pester test, otherwise is fails. #; `$var -eq `$true #Here you declare any variable(s) you need to complete the test. $example = $exampleRaw -replace "`n.*" -replace "PS C:\\>" Describe "Specific example testing for $commandName" { It "Example - $example" { # mock the tested command so we don't actually do anything # because it can be unsafe and we don't have the environment setup # (so the only thing we are testing is that the code is semantically # correct and provides all the needed params) Mock $commandName { # I am returning true here, # but some of the examples drill down to the returned object # so in strict mode we would fail $true } # here simply invoke the example $result = Invoke-Expression $example # and check that we got result from the mock $result | Should -BeTrue } } ################################### New Example test ################################### $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`"" #Remember to escape any variables names in the line above. #Remember to you need to output $true to the pester test, otherwise is fails. #; `$var -eq `$true #Here you declare any variable(s) you need to complete the test. $example = $exampleRaw -replace "`n.*" -replace "PS C:\\>" Describe "Specific example testing for $commandName" { It "Example - $example" { # mock the tested command so we don't actually do anything # because it can be unsafe and we don't have the environment setup # (so the only thing we are testing is that the code is semantically # correct and provides all the needed params) Mock $commandName { # I am returning true here, # but some of the examples drill down to the returned object # so in strict mode we would fail $true } # here simply invoke the example $result = Invoke-Expression $example # and check that we got result from the mock $result | Should -BeTrue } } ################################### New Example test ################################### $exampleRaw = "Import-D365Bacpac -ImportModeTier1 -BacpacFile `"C:\temp\uat.bacpac`" -NewDatabaseName `"ImportedDatabase`" -DiagnosticFile `"C:\temp\ImportLog.txt`"" #Remember to escape any variables names in the line above. #Remember to you need to output $true to the pester test, otherwise is fails. #; `$var -eq `$true #Here you declare any variable(s) you need to complete the test. $example = $exampleRaw -replace "`n.*" -replace "PS C:\\>" Describe "Specific example testing for $commandName" { It "Example - $example" { # mock the tested command so we don't actually do anything # because it can be unsafe and we don't have the environment setup # (so the only thing we are testing is that the code is semantically # correct and provides all the needed params) Mock $commandName { # I am returning true here, # but some of the examples drill down to the returned object # so in strict mode we would fail $true } # here simply invoke the example $result = Invoke-Expression $example # and check that we got result from the mock $result | Should -BeTrue } } ################################### Entire help loaded ################################### <# NAME Import-D365Bacpac SYNOPSIS Import a bacpac file SYNTAX Import-D365Bacpac [-ImportModeTier1] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [-BacpacFile] [-NewDatabaseName] [[-CustomSqlFile] ] [-DiagnosticFil e ] [-ImportOnly] [-EnableException] [] Import-D365Bacpac [-ImportModeTier2] [[-DatabaseServer] ] [[-DatabaseName] ] [-SqlUser] [- SqlPwd] [-BacpacFile] [-NewDatabaseName] [[-AxDeployExtUserPwd] ] [[-AxDbAdminPw d] ] [[-AxRuntimeUserPwd] ] [[-AxMrRuntimeUserPwd] ] [[-AxRetailRuntimeUserPwd] ] [ [-AxRetailDataSyncUserPwd] ] [[-AxDbReadonlyUserPwd] ] [[-CustomSqlFile] ] [-DiagnosticFile ] -ImportOnly [-EnableException] [] Import-D365Bacpac [-ImportModeTier2] [[-DatabaseServer] ] [[-DatabaseName] ] [-SqlUser] [- SqlPwd] [-BacpacFile] [-NewDatabaseName] [-AxDeployExtUserPwd] [-AxDbAdminPwd] [-AxRuntimeUserPwd] [-AxMrRuntimeUserPwd] [-AxRetailRuntimeUserPwd] [-AxRetailD ataSyncUserPwd] [-AxDbReadonlyUserPwd] [[-CustomSqlFile] ] [-DiagnosticFile ] [-E nableException] [] DESCRIPTION Import a bacpac file to either a Tier1 or Tier2 environment PARAMETERS -ImportModeTier1 [] Switch to instruct the cmdlet that it will import into a Tier1 environment The cmdlet will expect to work against a SQL Server instance Required? true Position? 1 Default value False Accept pipeline input? false Accept wildcard characters? false -ImportModeTier2 [] Switch to instruct the cmdlet that it will import into a Tier2 environment The cmdlet will expect to work against an Azure DB instance Required? true Position? 1 Default value False Accept pipeline input? false Accept wildcard characters? false -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net Required? false Position? 2 Default value $Script:DatabaseServer Accept pipeline input? false Accept wildcard characters? false -DatabaseName The name of the database Required? false Position? 3 Default value $Script:DatabaseName Accept pipeline input? false Accept wildcard characters? false -SqlUser The login name for the SQL Server instance Required? false Position? 4 Default value $Script:DatabaseUserName Accept pipeline input? false Accept wildcard characters? false -SqlPwd The password for the SQL Server user Required? false Position? 5 Default value $Script:DatabaseUserPassword Accept pipeline input? false Accept wildcard characters? false -BacpacFile Path to the bacpac file you want to import into the database server Required? true Position? 6 Default value Accept pipeline input? true (ByPropertyName) Accept wildcard characters? false -NewDatabaseName Name of the new database that will be created while importing the bacpac file This will create a new database on the database server and import the content of the bacpac into Required? true Position? 7 Default value Accept pipeline input? false Accept wildcard characters? false -AxDeployExtUserPwd Password that is obtained from LCS Required? false Position? 8 Default value Accept pipeline input? false Accept wildcard characters? false -AxDbAdminPwd Password that is obtained from LCS Required? false Position? 9 Default value Accept pipeline input? false Accept wildcard characters? false -AxRuntimeUserPwd Password that is obtained from LCS Required? false Position? 10 Default value Accept pipeline input? false Accept wildcard characters? false -AxMrRuntimeUserPwd Password that is obtained from LCS Required? false Position? 11 Default value Accept pipeline input? false Accept wildcard characters? false -AxRetailRuntimeUserPwd Password that is obtained from LCS Required? false Position? 12 Default value Accept pipeline input? false Accept wildcard characters? false -AxRetailDataSyncUserPwd Password that is obtained from LCS Required? false Position? 13 Default value Accept pipeline input? false Accept wildcard characters? false -AxDbReadonlyUserPwd Password that is obtained from LCS Required? false Position? 14 Default value Accept pipeline input? false Accept wildcard characters? false -CustomSqlFile Path to the sql script file that you want the cmdlet to execute against your data after it has been imported Required? false Position? 15 Default value Accept pipeline input? false Accept wildcard characters? false -DiagnosticFile Path to where you want the import to output a diagnostics file to assist you in troubleshooting the import Required? false Position? named Default value Accept pipeline input? false Accept wildcard characters? false -ImportOnly [] Switch to instruct the cmdlet to only import the bacpac into the new database The cmdlet will create a new database and import the content of the bacpac file into this Nothing else will be executed Required? false Position? named Default value False Accept pipeline input? false Accept wildcard characters? false -EnableException [] This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts Required? false Position? named Default value False Accept pipeline input? false Accept wildcard characters? false This cmdlet supports the common parameters: Verbose, Debug, ErrorAction, ErrorVariable, WarningAction, WarningVariable, OutBuffer, PipelineVariable, and OutVariable. For more information, see about_CommonParameters (https:/go.microsoft.com/fwlink/?LinkID=113216). INPUTS OUTPUTS NOTES Tags: Database, Bacpac, Tier1, Tier2, Golden Config, Config, Configuration Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) -------------------------- EXAMPLE 1 -------------------------- PS C:\>Import-D365Bacpac -ImportModeTier1 -BacpacFile "C:\temp\uat.bacpac" -NewDatabaseName "ImportedDatabase" PS C:\> Switch-D365ActiveDatabase -NewDatabaseName "ImportedDatabase" This will instruct the cmdlet that the import will be working against a SQL Server instance. It will import the "C:\temp\uat.bacpac" file into a new database named "ImportedDatabase". The next thing to do is to switch the active database out with the new one you just imported. "ImportedDatabase" will be switched in as the active database, while the old one will be named "AXDB_original". -------------------------- EXAMPLE 2 -------------------------- PS C:\>Import-D365Bacpac -ImportModeTier2 -SqlUser "sqladmin" -SqlPwd "XyzXyz" -BacpacFile "C:\temp\uat.bacpac" -Ax DeployExtUserPwd "XxXx" -AxDbAdminPwd "XxXx" -AxRuntimeUserPwd "XxXx" -AxMrRuntimeUserPwd "XxXx" -AxRetailRuntimeUs erPwd "XxXx" -AxRetailDataSyncUserPwd "XxXx" -AxDbReadonlyUserPwd "XxXx" -NewDatabaseName "ImportedDatabase" PS C:\> Switch-D365ActiveDatabase -NewDatabaseName "ImportedDatabase" -SqlUser "sqladmin" -SqlPwd "XyzXyz" This will instruct the cmdlet that the import will be working against an Azure DB instance. It requires all relevant passwords from LCS for all the builtin user accounts used in a Tier 2 environment. It will import the "C:\temp\uat.bacpac" file into a new database named "ImportedDatabase". The next thing to do is to switch the active database out with the new one you just imported. "ImportedDatabase" will be switched in as the active database, while the old one will be named "AXDB_original". -------------------------- EXAMPLE 3 -------------------------- PS C:\>Import-D365Bacpac -ImportModeTier1 -BacpacFile "C:\temp\uat.bacpac" -NewDatabaseName "ImportedDatabase" -Dia gnosticFile "C:\temp\ImportLog.txt" This will instruct the cmdlet that the import will be working against a SQL Server instance. It will import the "C:\temp\uat.bacpac" file into a new database named "ImportedDatabase". It will output a diagnostic file to "C:\temp\ImportLog.txt". RELATED LINKS #> ================================================ FILE: d365fo.tools/tests/examples/Test-TrustedConnection.Tests.ps1 ================================================ $commandName = "Test-TrustedConnection" ################################### New Example test ################################### $exampleRaw = "`$UseTrustedConnection = Test-TrustedConnection `$PSBoundParameters; `$UseTrustedConnection -eq `$true" #Remember to escape any variables names in the line above. #Remember to you need to output $true to the pester test, otherwise is fails. #; `$var -eq `$true #Here you declare any variable(s) you need to complete the test. $example = $exampleRaw -replace "`n.*" -replace "PS C:\\>" Describe "Specific example testing for $commandName" { It "Example - $example" { # mock the tested command so we don't actually do anything # because it can be unsafe and we don't have the environment setup # (so the only thing we are testing is that the code is semantically # correct and provides all the needed params) Mock $commandName { # I am returning true here, # but some of the examples drill down to the returned object # so in strict mode we would fail $true } # here simply invoke the example $result = Invoke-Expression $example # and check that we got result from the mock $result | Should -BeTrue } } ================================================ FILE: d365fo.tools/tests/functions/Add-D365AzureStorageConfig.Tests.ps1 ================================================ Describe "Add-D365AzureStorageConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Add-D365AzureStorageConfig).ParameterSets.Name | Should -Be 'AccessToken', 'SAS' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Add-D365AzureStorageConfig).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AccountId' { $parameter = (Get-Command Add-D365AzureStorageConfig).Parameters['AccountId'] $parameter.Name | Should -Be 'AccountId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AccessToken' { $parameter = (Get-Command Add-D365AzureStorageConfig).Parameters['AccessToken'] $parameter.Name | Should -Be 'AccessToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'AccessToken' $parameter.ParameterSets.Keys | Should -Contain 'AccessToken' $parameter.ParameterSets['AccessToken'].IsMandatory | Should -Be $True $parameter.ParameterSets['AccessToken'].Position | Should -Be -2147483648 $parameter.ParameterSets['AccessToken'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['AccessToken'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['AccessToken'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SAS' { $parameter = (Get-Command Add-D365AzureStorageConfig).Parameters['SAS'] $parameter.Name | Should -Be 'SAS' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'SAS' $parameter.ParameterSets.Keys | Should -Contain 'SAS' $parameter.ParameterSets['SAS'].IsMandatory | Should -Be $True $parameter.ParameterSets['SAS'].Position | Should -Be -2147483648 $parameter.ParameterSets['SAS'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['SAS'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['SAS'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Container' { $parameter = (Get-Command Add-D365AzureStorageConfig).Parameters['Container'] $parameter.Name | Should -Be 'Container' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Temporary' { $parameter = (Get-Command Add-D365AzureStorageConfig).Parameters['Temporary'] $parameter.Name | Should -Be 'Temporary' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Add-D365AzureStorageConfig).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset AccessToken" { <# AccessToken -Name -AccountId -AccessToken -Container AccessToken -Name -AccountId -AccessToken -Container -Temporary -Force #> } Describe "Testing parameterset SAS" { <# SAS -Name -AccountId -SAS -Container SAS -Name -AccountId -SAS -Container -Temporary -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/Add-D365BroadcastMessageConfig.Tests.ps1 ================================================ Describe "Add-D365BroadcastMessageConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Add-D365BroadcastMessageConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Tenant' { $parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['Tenant'] $parameter.Name | Should -Be 'Tenant' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter URL' { $parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['URL'] $parameter.Name | Should -Be 'URL' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ClientId' { $parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['ClientId'] $parameter.Name | Should -Be 'ClientId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ClientSecret' { $parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['ClientSecret'] $parameter.Name | Should -Be 'ClientSecret' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter TimeZone' { $parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['TimeZone'] $parameter.Name | Should -Be 'TimeZone' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EndingInMinutes' { $parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['EndingInMinutes'] $parameter.Name | Should -Be 'EndingInMinutes' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OnPremise' { $parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['OnPremise'] $parameter.Name | Should -Be 'OnPremise' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Temporary' { $parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['Temporary'] $parameter.Name | Should -Be 'Temporary' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Add-D365BroadcastMessageConfig).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Name __AllParameterSets -Name -Tenant -URL -ClientId -ClientSecret -TimeZone -EndingInMinutes -OnPremise -Temporary -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/Add-D365ModuleToRemove.Tests.ps1 ================================================ Describe "Add-D365ModuleToRemove Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Add-D365ModuleToRemove).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ModuleToRemove' { $parameter = (Get-Command Add-D365ModuleToRemove).Parameters['ModuleToRemove'] $parameter.Name | Should -Be 'ModuleToRemove' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DeployablePackage' { $parameter = (Get-Command Add-D365ModuleToRemove).Parameters['DeployablePackage'] $parameter.Name | Should -Be 'DeployablePackage' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Add-D365ModuleToRemove).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -ModuleToRemove -DeployablePackage __AllParameterSets -ModuleToRemove -DeployablePackage -OutputPath #> } } ================================================ FILE: d365fo.tools/tests/functions/Add-D365RsatWifConfigAuthorityThumbprint.Tests.ps1 ================================================ Describe "Add-D365RsatWifConfigAuthorityThumbprint Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Add-D365RsatWifConfigAuthorityThumbprint).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter CertificateThumbprint' { $parameter = (Get-Command Add-D365RsatWifConfigAuthorityThumbprint).Parameters['CertificateThumbprint'] $parameter.Name | Should -Be 'CertificateThumbprint' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -CertificateThumbprint __AllParameterSets -CertificateThumbprint #> } } ================================================ FILE: d365fo.tools/tests/functions/Add-D365WindowsDefenderRules.Tests.ps1 ================================================ Describe "Add-D365WindowsDefenderRules Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Add-D365WindowsDefenderRules).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Silent' { $parameter = (Get-Command Add-D365WindowsDefenderRules).Parameters['Silent'] $parameter.Name | Should -Be 'Silent' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Silent #> } } ================================================ FILE: d365fo.tools/tests/functions/Backup-D365DevConfig.Tests.ps1 ================================================ Describe "Backup-D365DevConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Backup-D365DevConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Backup-D365DevConfig).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Backup-D365DevConfig).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/Backup-D365MetaDataDir.Tests.ps1 ================================================ Describe "Backup-D365MetaDataDir Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Backup-D365MetaDataDir).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Backup-D365MetaDataDir).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BackupDir' { $parameter = (Get-Command Backup-D365MetaDataDir).Parameters['BackupDir'] $parameter.Name | Should -Be 'BackupDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -MetaDataDir -BackupDir #> } } ================================================ FILE: d365fo.tools/tests/functions/Backup-D365Runbook.Tests.ps1 ================================================ Describe "Backup-D365Runbook Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Backup-D365Runbook).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter File' { $parameter = (Get-Command Backup-D365Runbook).Parameters['File'] $parameter.Name | Should -Be 'File' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DestinationPath' { $parameter = (Get-Command Backup-D365Runbook).Parameters['DestinationPath'] $parameter.Name | Should -Be 'DestinationPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Backup-D365Runbook).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -File __AllParameterSets -File -DestinationPath -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/Backup-D365WebConfig.Tests.ps1 ================================================ Describe "Backup-D365WebConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Backup-D365WebConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Backup-D365WebConfig).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Backup-D365WebConfig).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/Backup-D365WifConfig.Tests.ps1 ================================================ Describe "Backup-D365WifConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Backup-D365WifConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Backup-D365WifConfig).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Backup-D365WifConfig).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/Clear-D365ActiveBroadcastMessageConfig.Tests.ps1 ================================================ Describe "Clear-D365ActiveBroadcastMessageConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Clear-D365ActiveBroadcastMessageConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Temporary' { $parameter = (Get-Command Clear-D365ActiveBroadcastMessageConfig).Parameters['Temporary'] $parameter.Name | Should -Be 'Temporary' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Temporary #> } } ================================================ FILE: d365fo.tools/tests/functions/Clear-D365BacpacObject.Tests.ps1 ================================================ Describe "Clear-D365BacpacObject Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Clear-D365BacpacObject).ParameterSets.Name | Should -Be 'Copy', 'Keep' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Clear-D365BacpacObject).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Clear-D365BacpacObject).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ObjectType' { $parameter = (Get-Command Clear-D365BacpacObject).Parameters['ObjectType'] $parameter.Name | Should -Be 'ObjectType' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Clear-D365BacpacObject).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Copy' $parameter.ParameterSets.Keys | Should -Contain 'Copy' $parameter.ParameterSets['Copy'].IsMandatory | Should -Be $True $parameter.ParameterSets['Copy'].Position | Should -Be -2147483648 $parameter.ParameterSets['Copy'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Copy'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Copy'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ClearFromSource' { $parameter = (Get-Command Clear-D365BacpacObject).Parameters['ClearFromSource'] $parameter.Name | Should -Be 'ClearFromSource' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Keep' $parameter.ParameterSets.Keys | Should -Contain 'Keep' $parameter.ParameterSets['Keep'].IsMandatory | Should -Be $True $parameter.ParameterSets['Keep'].Position | Should -Be -2147483648 $parameter.ParameterSets['Keep'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Keep'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Keep'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Copy" { <# Copy -Path -Name -OutputPath Copy -Path -Name -ObjectType -OutputPath #> } Describe "Testing parameterset Keep" { <# Keep -Path -Name -ClearFromSource Keep -Path -Name -ObjectType -ClearFromSource #> } } ================================================ FILE: d365fo.tools/tests/functions/Clear-D365BacpacTableData.Tests.ps1 ================================================ Describe "Clear-D365BacpacTableData Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Clear-D365BacpacTableData).ParameterSets.Name | Should -Be 'Copy', 'Keep' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Clear-D365BacpacTableData).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Table' { $parameter = (Get-Command Clear-D365BacpacTableData).Parameters['Table'] $parameter.Name | Should -Be 'Table' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Clear-D365BacpacTableData).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Copy' $parameter.ParameterSets.Keys | Should -Contain 'Copy' $parameter.ParameterSets['Copy'].IsMandatory | Should -Be $True $parameter.ParameterSets['Copy'].Position | Should -Be -2147483648 $parameter.ParameterSets['Copy'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Copy'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Copy'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ClearFromSource' { $parameter = (Get-Command Clear-D365BacpacTableData).Parameters['ClearFromSource'] $parameter.Name | Should -Be 'ClearFromSource' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Keep' $parameter.ParameterSets.Keys | Should -Contain 'Keep' $parameter.ParameterSets['Keep'].IsMandatory | Should -Be $True $parameter.ParameterSets['Keep'].Position | Should -Be -2147483648 $parameter.ParameterSets['Keep'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Keep'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Keep'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Copy" { <# Copy -Path -Table -OutputPath Copy -Path -Table -OutputPath #> } Describe "Testing parameterset Keep" { <# Keep -Path -Table -ClearFromSource Keep -Path -Table -ClearFromSource #> } } ================================================ FILE: d365fo.tools/tests/functions/Clear-D365MonitorData.Tests.ps1 ================================================ Describe "Clear-D365MonitorData Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Clear-D365MonitorData).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Clear-D365MonitorData).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Path #> } } ================================================ FILE: d365fo.tools/tests/functions/Clear-D365TempDbTables.Tests.ps1 ================================================ Describe "Clear-D365TempDbTables Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Clear-D365TempDbTables).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Clear-D365TempDbTables).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Clear-D365TempDbTables).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Clear-D365TempDbTables).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Clear-D365TempDbTables).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Days' { $parameter = (Get-Command Clear-D365TempDbTables).Parameters['Days'] $parameter.Name | Should -Be 'Days' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Clear-D365TempDbTables).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -Days -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/ConvertTo-D365Dacpac.Tests.ps1 ================================================ Describe "ConvertTo-D365Dacpac Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command ConvertTo-D365Dacpac).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command ConvertTo-D365Dacpac).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path __AllParameterSets -Path #> } } ================================================ FILE: d365fo.tools/tests/functions/Disable-D365Exception.Tests.ps1 ================================================ Describe "Disable-D365Exception Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Disable-D365Exception).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Disable-D365Flight.Tests.ps1 ================================================ Describe "Disable-D365Flight Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Disable-D365Flight).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter FlightName' { $parameter = (Get-Command Disable-D365Flight).Parameters['FlightName'] $parameter.Name | Should -Be 'FlightName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Disable-D365Flight).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Disable-D365Flight).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Disable-D365Flight).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Disable-D365Flight).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -FlightName __AllParameterSets -FlightName -DatabaseServer -DatabaseName -SqlUser -SqlPwd #> } } ================================================ FILE: d365fo.tools/tests/functions/Disable-D365IISPreload.Tests.ps1 ================================================ Describe "Disable-D365IISPreload Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Disable-D365IISPreload).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Disable-D365MaintenanceMode.Tests.ps1 ================================================ Describe "Disable-D365MaintenanceMode Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Disable-D365MaintenanceMode).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Disable-D365MaintenanceMode).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -MetaDataDir -BinDir -DatabaseServer -DatabaseName -SqlUser -SqlPwd -LogPath -ShowOriginalProgress -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Disable-D365SqlChangeTracking.Tests.ps1 ================================================ Describe "Disable-D365SqlChangeTracking Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Disable-D365SqlChangeTracking).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Disable-D365SqlChangeTracking).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Disable-D365SqlChangeTracking).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Disable-D365SqlChangeTracking).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Disable-D365SqlChangeTracking).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Disable-D365SqlChangeTracking).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Disable-D365User.Tests.ps1 ================================================ Describe "Disable-D365User Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Disable-D365User).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Disable-D365User).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Disable-D365User).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Disable-D365User).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Disable-D365User).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Email' { $parameter = (Get-Command Disable-D365User).Parameters['Email'] $parameter.Name | Should -Be 'Email' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -Email #> } } ================================================ FILE: d365fo.tools/tests/functions/Enable-D365Exception.Tests.ps1 ================================================ Describe "Enable-D365Exception Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Enable-D365Exception).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Enable-D365Flight.Tests.ps1 ================================================ Describe "Enable-D365Flight Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Enable-D365Flight).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter FlightName' { $parameter = (Get-Command Enable-D365Flight).Parameters['FlightName'] $parameter.Name | Should -Be 'FlightName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Enable-D365Flight).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Enable-D365Flight).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Enable-D365Flight).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Enable-D365Flight).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -FlightName __AllParameterSets -FlightName -DatabaseServer -DatabaseName -SqlUser -SqlPwd #> } } ================================================ FILE: d365fo.tools/tests/functions/Enable-D365IISPreload.Tests.ps1 ================================================ Describe "Enable-D365IISPreload Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Enable-D365IISPreload).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter BaseUrl' { $parameter = (Get-Command Enable-D365IISPreload).Parameters['BaseUrl'] $parameter.Name | Should -Be 'BaseUrl' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -BaseUrl #> } } ================================================ FILE: d365fo.tools/tests/functions/Enable-D365MaintenanceMode.Tests.ps1 ================================================ Describe "Enable-D365MaintenanceMode Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Enable-D365MaintenanceMode).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Enable-D365MaintenanceMode).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -MetaDataDir -BinDir -DatabaseServer -DatabaseName -SqlUser -SqlPwd -LogPath -ShowOriginalProgress -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Enable-D365SqlChangeTracking.Tests.ps1 ================================================ Describe "Enable-D365SqlChangeTracking Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Enable-D365SqlChangeTracking).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Enable-D365SqlChangeTracking).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Enable-D365SqlChangeTracking).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Enable-D365SqlChangeTracking).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Enable-D365SqlChangeTracking).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Enable-D365SqlChangeTracking).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Enable-D365User.Tests.ps1 ================================================ Describe "Enable-D365User Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Enable-D365User).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Enable-D365User).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Enable-D365User).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Enable-D365User).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Enable-D365User).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Email' { $parameter = (Get-Command Enable-D365User).Parameters['Email'] $parameter.Name | Should -Be 'Email' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -Email #> } } ================================================ FILE: d365fo.tools/tests/functions/Export-D365BacpacModelFile.Tests.ps1 ================================================ Describe "Export-D365BacpacModelFile Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Export-D365BacpacModelFile).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Export-D365BacpacModelFile).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Export-D365BacpacModelFile).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Export-D365BacpacModelFile).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path __AllParameterSets -Path -OutputPath -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/Export-D365Model.Tests.ps1 ================================================ Describe "Export-D365Model Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Export-D365Model).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Export-D365Model).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Model' { $parameter = (Get-Command Export-D365Model).Parameters['Model'] $parameter.Name | Should -Be 'Model' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Export-D365Model).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Export-D365Model).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Export-D365Model).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Export-D365Model).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Export-D365Model).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Export-D365Model).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path -Model __AllParameterSets -Path -Model -Force -BinDir -MetaDataDir -LogPath -ShowOriginalProgress -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Export-D365SecurityDetails.Tests.ps1 ================================================ Describe "Export-D365SecurityDetails Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Export-D365SecurityDetails).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter FilePath' { $parameter = (Get-Command Export-D365SecurityDetails).Parameters['FilePath'] $parameter.Name | Should -Be 'FilePath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputDirectory' { $parameter = (Get-Command Export-D365SecurityDetails).Parameters['OutputDirectory'] $parameter.Name | Should -Be 'OutputDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -FilePath __AllParameterSets -FilePath -OutputDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Find-D365Command.Tests.ps1 ================================================ Describe "Find-D365Command Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Find-D365Command).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Pattern' { $parameter = (Get-Command Find-D365Command).Parameters['Pattern'] $parameter.Name | Should -Be 'Pattern' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Tag' { $parameter = (Get-Command Find-D365Command).Parameters['Tag'] $parameter.Name | Should -Be 'Tag' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Author' { $parameter = (Get-Command Find-D365Command).Parameters['Author'] $parameter.Name | Should -Be 'Author' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MinimumVersion' { $parameter = (Get-Command Find-D365Command).Parameters['MinimumVersion'] $parameter.Name | Should -Be 'MinimumVersion' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MaximumVersion' { $parameter = (Get-Command Find-D365Command).Parameters['MaximumVersion'] $parameter.Name | Should -Be 'MaximumVersion' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Rebuild' { $parameter = (Get-Command Find-D365Command).Parameters['Rebuild'] $parameter.Name | Should -Be 'Rebuild' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Find-D365Command).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Pattern -Tag -Author -MinimumVersion -MaximumVersion -Rebuild -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365AOTObject.Tests.ps1 ================================================ Describe "Get-D365AOTObject Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365AOTObject).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Get-D365AOTObject).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ObjectType' { $parameter = (Get-Command Get-D365AOTObject).Parameters['ObjectType'] $parameter.Name | Should -Be 'ObjectType' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365AOTObject).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SearchInPackages' { $parameter = (Get-Command Get-D365AOTObject).Parameters['SearchInPackages'] $parameter.Name | Should -Be 'SearchInPackages' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter IncludePath' { $parameter = (Get-Command Get-D365AOTObject).Parameters['IncludePath'] $parameter.Name | Should -Be 'IncludePath' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path __AllParameterSets -Path -ObjectType -Name -SearchInPackages -IncludePath #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365ActiveAzureStorageConfig.Tests.ps1 ================================================ Describe "Get-D365ActiveAzureStorageConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365ActiveAzureStorageConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputAsPsCustomObject' { $parameter = (Get-Command Get-D365ActiveAzureStorageConfig).Parameters['OutputAsPsCustomObject'] $parameter.Name | Should -Be 'OutputAsPsCustomObject' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputAsPsCustomObject #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365ActiveBroadcastMessageConfig.Tests.ps1 ================================================ Describe "Get-D365ActiveBroadcastMessageConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365ActiveBroadcastMessageConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputAsHashtable' { $parameter = (Get-Command Get-D365ActiveBroadcastMessageConfig).Parameters['OutputAsHashtable'] $parameter.Name | Should -Be 'OutputAsHashtable' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputAsHashtable #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365AzureDevOpsNuget.Tests.ps1 ================================================ Describe "Get-D365AzureDevOpsNuget Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365AzureDevOpsNuget).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Url' { $parameter = (Get-Command Get-D365AzureDevOpsNuget).Parameters['Url'] $parameter.Name | Should -Be 'Url' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FeedName' { $parameter = (Get-Command Get-D365AzureDevOpsNuget).Parameters['FeedName'] $parameter.Name | Should -Be 'FeedName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PeronalAccessToken' { $parameter = (Get-Command Get-D365AzureDevOpsNuget).Parameters['PeronalAccessToken'] $parameter.Name | Should -Be 'PeronalAccessToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365AzureDevOpsNuget).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Latest' { $parameter = (Get-Command Get-D365AzureDevOpsNuget).Parameters['Latest'] $parameter.Name | Should -Be 'Latest' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Url -FeedName -PeronalAccessToken __AllParameterSets -Url -FeedName -PeronalAccessToken -Name -Latest #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365AzureStorageConfig.Tests.ps1 ================================================ Describe "Get-D365AzureStorageConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365AzureStorageConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365AzureStorageConfig).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputAsHashtable' { $parameter = (Get-Command Get-D365AzureStorageConfig).Parameters['OutputAsHashtable'] $parameter.Name | Should -Be 'OutputAsHashtable' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Name -OutputAsHashtable #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365AzureStorageFile.Tests.ps1 ================================================ Describe "Get-D365AzureStorageFile Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365AzureStorageFile).ParameterSets.Name | Should -Be 'Default', 'Latest' } It 'Should have the expected parameter AccountId' { $parameter = (Get-Command Get-D365AzureStorageFile).Parameters['AccountId'] $parameter.Name | Should -Be 'AccountId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AccessToken' { $parameter = (Get-Command Get-D365AzureStorageFile).Parameters['AccessToken'] $parameter.Name | Should -Be 'AccessToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SAS' { $parameter = (Get-Command Get-D365AzureStorageFile).Parameters['SAS'] $parameter.Name | Should -Be 'SAS' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Container' { $parameter = (Get-Command Get-D365AzureStorageFile).Parameters['Container'] $parameter.Name | Should -Be 'Container' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365AzureStorageFile).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be -2147483648 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Latest' { $parameter = (Get-Command Get-D365AzureStorageFile).Parameters['Latest'] $parameter.Name | Should -Be 'Latest' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Latest' $parameter.ParameterSets.Keys | Should -Contain 'Latest' $parameter.ParameterSets['Latest'].IsMandatory | Should -Be $True $parameter.ParameterSets['Latest'].Position | Should -Be -2147483648 $parameter.ParameterSets['Latest'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Latest'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Latest'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -AccountId -AccessToken -SAS -Container -Name #> } Describe "Testing parameterset Latest" { <# Latest -Latest Latest -AccountId -AccessToken -SAS -Container -Latest #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365AzureStorageUrl.Tests.ps1 ================================================ Describe "Get-D365AzureStorageUrl Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365AzureStorageUrl).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter AccountId' { $parameter = (Get-Command Get-D365AzureStorageUrl).Parameters['AccountId'] $parameter.Name | Should -Be 'AccountId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SAS' { $parameter = (Get-Command Get-D365AzureStorageUrl).Parameters['SAS'] $parameter.Name | Should -Be 'SAS' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Container' { $parameter = (Get-Command Get-D365AzureStorageUrl).Parameters['Container'] $parameter.Name | Should -Be 'Container' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputAsHashtable' { $parameter = (Get-Command Get-D365AzureStorageUrl).Parameters['OutputAsHashtable'] $parameter.Name | Should -Be 'OutputAsHashtable' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -AccountId -SAS -Container -OutputAsHashtable #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365BacpacSqlOptions.Tests.ps1 ================================================ Describe "Get-D365BacpacSqlOptions Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365BacpacSqlOptions).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Get-D365BacpacSqlOptions).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Path #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365BacpacTable.Tests.ps1 ================================================ Describe "Get-D365BacpacTable Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365BacpacTable).ParameterSets.Name | Should -Be 'Default', 'SortSizeAsc', 'SortSizeDesc' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Get-D365BacpacTable).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Table' { $parameter = (Get-Command Get-D365BacpacTable).Parameters['Table'] $parameter.Name | Should -Be 'Table' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Top' { $parameter = (Get-Command Get-D365BacpacTable).Parameters['Top'] $parameter.Name | Should -Be 'Top' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SortSizeAsc' { $parameter = (Get-Command Get-D365BacpacTable).Parameters['SortSizeAsc'] $parameter.Name | Should -Be 'SortSizeAsc' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'SortSizeAsc' $parameter.ParameterSets.Keys | Should -Contain 'SortSizeAsc' $parameter.ParameterSets['SortSizeAsc'].IsMandatory | Should -Be $False $parameter.ParameterSets['SortSizeAsc'].Position | Should -Be -2147483648 $parameter.ParameterSets['SortSizeAsc'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['SortSizeAsc'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['SortSizeAsc'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SortSizeDesc' { $parameter = (Get-Command Get-D365BacpacTable).Parameters['SortSizeDesc'] $parameter.Name | Should -Be 'SortSizeDesc' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'SortSizeDesc' $parameter.ParameterSets.Keys | Should -Contain 'SortSizeDesc' $parameter.ParameterSets['SortSizeDesc'].IsMandatory | Should -Be $False $parameter.ParameterSets['SortSizeDesc'].Position | Should -Be -2147483648 $parameter.ParameterSets['SortSizeDesc'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['SortSizeDesc'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['SortSizeDesc'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -Path Default -Path -Table -Top #> } Describe "Testing parameterset SortSizeAsc" { <# SortSizeAsc -Path SortSizeAsc -Path -Table -Top -SortSizeAsc #> } Describe "Testing parameterset SortSizeDesc" { <# SortSizeDesc -Path SortSizeDesc -Path -Table -Top -SortSizeDesc #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365BroadcastMessage.Tests.ps1 ================================================ Describe "Get-D365BroadcastMessage Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365BroadcastMessage).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Get-D365BroadcastMessage).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Get-D365BroadcastMessage).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Get-D365BroadcastMessage).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Get-D365BroadcastMessage).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ExcludeExpired' { $parameter = (Get-Command Get-D365BroadcastMessage).Parameters['ExcludeExpired'] $parameter.Name | Should -Be 'ExcludeExpired' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -ExcludeExpired #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365BroadcastMessageConfig.Tests.ps1 ================================================ Describe "Get-D365BroadcastMessageConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365BroadcastMessageConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365BroadcastMessageConfig).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputAsHashtable' { $parameter = (Get-Command Get-D365BroadcastMessageConfig).Parameters['OutputAsHashtable'] $parameter.Name | Should -Be 'OutputAsHashtable' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Name -OutputAsHashtable #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365ClickOnceTrustPrompt.Tests.ps1 ================================================ Describe "Get-D365ClickOnceTrustPrompt Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365ClickOnceTrustPrompt).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365CompilerResult.Tests.ps1 ================================================ Describe "Get-D365CompilerResult Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365CompilerResult).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Get-D365CompilerResult).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ErrorsOnly' { $parameter = (Get-Command Get-D365CompilerResult).Parameters['ErrorsOnly'] $parameter.Name | Should -Be 'ErrorsOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputTotals' { $parameter = (Get-Command Get-D365CompilerResult).Parameters['OutputTotals'] $parameter.Name | Should -Be 'OutputTotals' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputAsObjects' { $parameter = (Get-Command Get-D365CompilerResult).Parameters['OutputAsObjects'] $parameter.Name | Should -Be 'OutputAsObjects' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path __AllParameterSets -Path -ErrorsOnly -OutputTotals -OutputAsObjects #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365Database.Tests.ps1 ================================================ Describe "Get-D365Database Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365Database).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365Database).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Get-D365Database).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Get-D365Database).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Get-D365Database).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Get-D365Database).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Name -DatabaseServer -DatabaseName -SqlUser -SqlPwd #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365DatabaseAccess.Tests.ps1 ================================================ Describe "Get-D365DatabaseAccess Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365DatabaseAccess).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365DecryptedWebConfig.Tests.ps1 ================================================ Describe "Get-D365DecryptedWebConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365DecryptedWebConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Get-D365DecryptedWebConfig).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AosServiceWebRootPath' { $parameter = (Get-Command Get-D365DecryptedWebConfig).Parameters['AosServiceWebRootPath'] $parameter.Name | Should -Be 'AosServiceWebRootPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -AosServiceWebRootPath #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365DefaultModelForNewProjects.Tests.ps1 ================================================ Describe "Get-D365DefaultModelForNewProjects Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365DefaultModelForNewProjects).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365DotNetClass.Tests.ps1 ================================================ Describe "Get-D365DotNetClass Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365DotNetClass).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365DotNetClass).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Assembly' { $parameter = (Get-Command Get-D365DotNetClass).Parameters['Assembly'] $parameter.Name | Should -Be 'Assembly' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 2 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Get-D365DotNetClass).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 3 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -Name -Assembly -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365DotNetMethod.Tests.ps1 ================================================ Describe "Get-D365DotNetMethod Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365DotNetMethod).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter Assembly' { $parameter = (Get-Command Get-D365DotNetMethod).Parameters['Assembly'] $parameter.Name | Should -Be 'Assembly' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365DotNetMethod).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 2 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter TypeName' { $parameter = (Get-Command Get-D365DotNetMethod).Parameters['TypeName'] $parameter.Name | Should -Be 'TypeName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 3 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -Assembly Default -Assembly -Name -TypeName #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365Environment.Tests.ps1 ================================================ Describe "Get-D365Environment Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365Environment).ParameterSets.Name | Should -Be 'Default', 'Specific' } It 'Should have the expected parameter ComputerName' { $parameter = (Get-Command Get-D365Environment).Parameters['ComputerName'] $parameter.Name | Should -Be 'ComputerName' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific', 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 1 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter All' { $parameter = (Get-Command Get-D365Environment).Parameters['All'] $parameter.Name | Should -Be 'All' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be -2147483648 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Aos' { $parameter = (Get-Command Get-D365Environment).Parameters['Aos'] $parameter.Name | Should -Be 'Aos' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be -2147483648 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Batch' { $parameter = (Get-Command Get-D365Environment).Parameters['Batch'] $parameter.Name | Should -Be 'Batch' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be -2147483648 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FinancialReporter' { $parameter = (Get-Command Get-D365Environment).Parameters['FinancialReporter'] $parameter.Name | Should -Be 'FinancialReporter' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be -2147483648 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DMF' { $parameter = (Get-Command Get-D365Environment).Parameters['DMF'] $parameter.Name | Should -Be 'DMF' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be -2147483648 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OnlyStartTypeAutomatic' { $parameter = (Get-Command Get-D365Environment).Parameters['OnlyStartTypeAutomatic'] $parameter.Name | Should -Be 'OnlyStartTypeAutomatic' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputServiceDetailsOnly' { $parameter = (Get-Command Get-D365Environment).Parameters['OutputServiceDetailsOnly'] $parameter.Name | Should -Be 'OutputServiceDetailsOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -ComputerName -All -OnlyStartTypeAutomatic -OutputServiceDetailsOnly #> } Describe "Testing parameterset Specific" { <# Specific - Specific -ComputerName -Aos -Batch -FinancialReporter -DMF -OnlyStartTypeAutomatic -OutputServiceDetailsOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365EnvironmentSettings.Tests.ps1 ================================================ Describe "Get-D365EnvironmentSettings Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365EnvironmentSettings).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365EventTraceProvider.Tests.ps1 ================================================ Describe "Get-D365EventTraceProvider Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365EventTraceProvider).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365EventTraceProvider).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Name #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365ExternalIP.Tests.ps1 ================================================ Describe "Get-D365ExternalIP Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365ExternalIP).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter SaveToClipboard' { $parameter = (Get-Command Get-D365ExternalIP).Parameters['SaveToClipboard'] $parameter.Name | Should -Be 'SaveToClipboard' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -SaveToClipboard #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365Flight.Tests.ps1 ================================================ Describe "Get-D365Flight Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365Flight).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter FlightName' { $parameter = (Get-Command Get-D365Flight).Parameters['FlightName'] $parameter.Name | Should -Be 'FlightName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Get-D365Flight).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Get-D365Flight).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Get-D365Flight).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Get-D365Flight).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -FlightName -DatabaseServer -DatabaseName -SqlUser -SqlPwd #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365IISPreload.Tests.ps1 ================================================ Describe "Get-D365IISPreload Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365IISPreload).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365InstalledHotfix.Tests.ps1 ================================================ Describe "Get-D365InstalledHotfix Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365InstalledHotfix).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Get-D365InstalledHotfix).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Get-D365InstalledHotfix).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 2 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Model' { $parameter = (Get-Command Get-D365InstalledHotfix).Parameters['Model'] $parameter.Name | Should -Be 'Model' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 3 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365InstalledHotfix).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 4 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter KB' { $parameter = (Get-Command Get-D365InstalledHotfix).Parameters['KB'] $parameter.Name | Should -Be 'KB' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 5 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -BinDir -PackageDirectory -Model -Name -KB #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365InstalledPackage.Tests.ps1 ================================================ Describe "Get-D365InstalledPackage Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365InstalledPackage).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365InstalledPackage).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Get-D365InstalledPackage).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Name -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365InstalledService.Tests.ps1 ================================================ Describe "Get-D365InstalledService Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365InstalledService).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Get-D365InstalledService).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -Path #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365InstanceName.Tests.ps1 ================================================ Describe "Get-D365InstanceName Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365InstanceName).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365JsonService.Tests.ps1 ================================================ Describe "Get-D365JsonService Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365JsonService).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365JsonService).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Url' { $parameter = (Get-Command Get-D365JsonService).Parameters['Url'] $parameter.Name | Should -Be 'Url' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Tenant' { $parameter = (Get-Command Get-D365JsonService).Parameters['Tenant'] $parameter.Name | Should -Be 'Tenant' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ClientId' { $parameter = (Get-Command Get-D365JsonService).Parameters['ClientId'] $parameter.Name | Should -Be 'ClientId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ClientSecret' { $parameter = (Get-Command Get-D365JsonService).Parameters['ClientSecret'] $parameter.Name | Should -Be 'ClientSecret' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RawOutput' { $parameter = (Get-Command Get-D365JsonService).Parameters['RawOutput'] $parameter.Name | Should -Be 'RawOutput' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputAsJson' { $parameter = (Get-Command Get-D365JsonService).Parameters['OutputAsJson'] $parameter.Name | Should -Be 'OutputAsJson' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Url -Tenant -ClientId -ClientSecret __AllParameterSets -Name -Url -Tenant -ClientId -ClientSecret -RawOutput -OutputAsJson #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365Label.Tests.ps1 ================================================ Describe "Get-D365Label Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365Label).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Get-D365Label).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LabelFileId' { $parameter = (Get-Command Get-D365Label).Parameters['LabelFileId'] $parameter.Name | Should -Be 'LabelFileId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be 2 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Language' { $parameter = (Get-Command Get-D365Label).Parameters['Language'] $parameter.Name | Should -Be 'Language' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 3 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365Label).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 4 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -LabelFileId Default -BinDir -LabelFileId -Language -Name #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365LabelFile.Tests.ps1 ================================================ Describe "Get-D365LabelFile Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365LabelFile).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Get-D365LabelFile).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Get-D365LabelFile).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 2 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Module' { $parameter = (Get-Command Get-D365LabelFile).Parameters['Module'] $parameter.Name | Should -Be 'Module' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 3 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365LabelFile).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 4 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -BinDir -PackageDirectory -Module -Name #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365Language.Tests.ps1 ================================================ Describe "Get-D365Language Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365Language).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Get-D365Language).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365Language).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 2 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -BinDir -Name #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365LcsApiConfig.Tests.ps1 ================================================ Describe "Get-D365LcsApiConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365LcsApiConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputAsHashtable' { $parameter = (Get-Command Get-D365LcsApiConfig).Parameters['OutputAsHashtable'] $parameter.Name | Should -Be 'OutputAsHashtable' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputAsHashtable #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365LcsApiToken.Tests.ps1 ================================================ Describe "Get-D365LcsApiToken Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365LcsApiToken).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ClientId' { $parameter = (Get-Command Get-D365LcsApiToken).Parameters['ClientId'] $parameter.Name | Should -Be 'ClientId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Username' { $parameter = (Get-Command Get-D365LcsApiToken).Parameters['Username'] $parameter.Name | Should -Be 'Username' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Password' { $parameter = (Get-Command Get-D365LcsApiToken).Parameters['Password'] $parameter.Name | Should -Be 'Password' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Get-D365LcsApiToken).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Get-D365LcsApiToken).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Username -Password __AllParameterSets -ClientId -Username -Password -LcsApiUri -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365LcsAssetFile.Tests.ps1 ================================================ Describe "Get-D365LcsAssetFile Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365LcsAssetFile).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Get-D365LcsAssetFile).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FileType' { $parameter = (Get-Command Get-D365LcsAssetFile).Parameters['FileType'] $parameter.Name | Should -Be 'FileType' $parameter.ParameterType.ToString() | Should -Be LcsAssetFileType $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AssetName' { $parameter = (Get-Command Get-D365LcsAssetFile).Parameters['AssetName'] $parameter.Name | Should -Be 'AssetName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AssetVersion' { $parameter = (Get-Command Get-D365LcsAssetFile).Parameters['AssetVersion'] $parameter.Name | Should -Be 'AssetVersion' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AssetFilename' { $parameter = (Get-Command Get-D365LcsAssetFile).Parameters['AssetFilename'] $parameter.Name | Should -Be 'AssetFilename' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AssetDescription' { $parameter = (Get-Command Get-D365LcsAssetFile).Parameters['AssetDescription'] $parameter.Name | Should -Be 'AssetDescription' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AssetId' { $parameter = (Get-Command Get-D365LcsAssetFile).Parameters['AssetId'] $parameter.Name | Should -Be 'AssetId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Get-D365LcsAssetFile).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Get-D365LcsAssetFile).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Latest' { $parameter = (Get-Command Get-D365LcsAssetFile).Parameters['Latest'] $parameter.Name | Should -Be 'Latest' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Get-D365LcsAssetFile).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 9 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Get-D365LcsAssetFile).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -ProjectId -FileType -AssetName -AssetVersion -AssetFilename -AssetDescription -AssetId -BearerToken -LcsApiUri -Latest -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365LcsAssetValidationStatus.Tests.ps1 ================================================ Describe "Get-D365LcsAssetValidationStatus Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365LcsAssetValidationStatus).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter AssetId' { $parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['AssetId'] $parameter.Name | Should -Be 'AssetId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter WaitForValidation' { $parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['WaitForValidation'] $parameter.Name | Should -Be 'WaitForValidation' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SleepInSeconds' { $parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['SleepInSeconds'] $parameter.Name | Should -Be 'SleepInSeconds' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Get-D365LcsAssetValidationStatus).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -AssetId __AllParameterSets -AssetId -ProjectId -BearerToken -LcsApiUri -WaitForValidation -SleepInSeconds -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365LcsDatabaseBackups.Tests.ps1 ================================================ Describe "Get-D365LcsDatabaseBackups Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365LcsDatabaseBackups).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Get-D365LcsDatabaseBackups).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Get-D365LcsDatabaseBackups).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Get-D365LcsDatabaseBackups).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Latest' { $parameter = (Get-Command Get-D365LcsDatabaseBackups).Parameters['Latest'] $parameter.Name | Should -Be 'Latest' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Get-D365LcsDatabaseBackups).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Get-D365LcsDatabaseBackups).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -ProjectId -BearerToken -LcsApiUri -Latest -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365LcsDatabaseOperationStatus.Tests.ps1 ================================================ Describe "Get-D365LcsDatabaseOperationStatus Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365LcsDatabaseOperationStatus).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OperationActivityId' { $parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['OperationActivityId'] $parameter.Name | Should -Be 'OperationActivityId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnvironmentId' { $parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['EnvironmentId'] $parameter.Name | Should -Be 'EnvironmentId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter WaitForCompletion' { $parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['WaitForCompletion'] $parameter.Name | Should -Be 'WaitForCompletion' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SleepInSeconds' { $parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['SleepInSeconds'] $parameter.Name | Should -Be 'SleepInSeconds' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Get-D365LcsDatabaseOperationStatus).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -OperationActivityId -EnvironmentId __AllParameterSets -ProjectId -BearerToken -OperationActivityId -EnvironmentId -LcsApiUri -WaitForCompletion -SleepInSeconds -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365LcsDeploymentStatus.Tests.ps1 ================================================ Describe "Get-D365LcsDeploymentStatus Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365LcsDeploymentStatus).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ActivityId' { $parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['ActivityId'] $parameter.Name | Should -Be 'ActivityId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnvironmentId' { $parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['EnvironmentId'] $parameter.Name | Should -Be 'EnvironmentId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter WaitForCompletion' { $parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['WaitForCompletion'] $parameter.Name | Should -Be 'WaitForCompletion' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SleepInSeconds' { $parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['SleepInSeconds'] $parameter.Name | Should -Be 'SleepInSeconds' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FailOnErrorMessage' { $parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['FailOnErrorMessage'] $parameter.Name | Should -Be 'FailOnErrorMessage' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Get-D365LcsDeploymentStatus).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -ActivityId -EnvironmentId __AllParameterSets -ProjectId -BearerToken -ActivityId -EnvironmentId -LcsApiUri -WaitForCompletion -SleepInSeconds -FailOnErrorMessage -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365LcsEnvironmentHistory.Tests.ps1 ================================================ Describe "Get-D365LcsEnvironmentHistory Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365LcsEnvironmentHistory).ParameterSets.Name | Should -Be 'Default', 'Pagination' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnvironmentId' { $parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['EnvironmentId'] $parameter.Name | Should -Be 'EnvironmentId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter TraverseAllPages' { $parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['TraverseAllPages'] $parameter.Name | Should -Be 'TraverseAllPages' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Pagination' $parameter.ParameterSets.Keys | Should -Contain 'Pagination' $parameter.ParameterSets['Pagination'].IsMandatory | Should -Be $False $parameter.ParameterSets['Pagination'].Position | Should -Be -2147483648 $parameter.ParameterSets['Pagination'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Pagination'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Pagination'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FirstPages' { $parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['FirstPages'] $parameter.Name | Should -Be 'FirstPages' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Pagination' $parameter.ParameterSets.Keys | Should -Contain 'Pagination' $parameter.ParameterSets['Pagination'].IsMandatory | Should -Be $False $parameter.ParameterSets['Pagination'].Position | Should -Be -2147483648 $parameter.ParameterSets['Pagination'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Pagination'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Pagination'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FailOnErrorMessage' { $parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['FailOnErrorMessage'] $parameter.Name | Should -Be 'FailOnErrorMessage' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Get-D365LcsEnvironmentHistory).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -EnvironmentId Default -ProjectId -BearerToken -EnvironmentId -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException #> } Describe "Testing parameterset Pagination" { <# Pagination -EnvironmentId Pagination -ProjectId -BearerToken -EnvironmentId -TraverseAllPages -FirstPages -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365LcsEnvironmentMetadata.Tests.ps1 ================================================ Describe "Get-D365LcsEnvironmentMetadata Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365LcsEnvironmentMetadata).ParameterSets.Name | Should -Be 'Default', 'SearchByEnvironmentId', 'SearchByEnvironmentName', 'Pagination' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnvironmentId' { $parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['EnvironmentId'] $parameter.Name | Should -Be 'EnvironmentId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'SearchByEnvironmentId' $parameter.ParameterSets.Keys | Should -Contain 'SearchByEnvironmentId' $parameter.ParameterSets['SearchByEnvironmentId'].IsMandatory | Should -Be $False $parameter.ParameterSets['SearchByEnvironmentId'].Position | Should -Be -2147483648 $parameter.ParameterSets['SearchByEnvironmentId'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['SearchByEnvironmentId'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['SearchByEnvironmentId'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnvironmentName' { $parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['EnvironmentName'] $parameter.Name | Should -Be 'EnvironmentName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'SearchByEnvironmentName' $parameter.ParameterSets.Keys | Should -Contain 'SearchByEnvironmentName' $parameter.ParameterSets['SearchByEnvironmentName'].IsMandatory | Should -Be $False $parameter.ParameterSets['SearchByEnvironmentName'].Position | Should -Be -2147483648 $parameter.ParameterSets['SearchByEnvironmentName'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['SearchByEnvironmentName'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['SearchByEnvironmentName'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter TraverseAllPages' { $parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['TraverseAllPages'] $parameter.Name | Should -Be 'TraverseAllPages' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Pagination' $parameter.ParameterSets.Keys | Should -Contain 'Pagination' $parameter.ParameterSets['Pagination'].IsMandatory | Should -Be $False $parameter.ParameterSets['Pagination'].Position | Should -Be -2147483648 $parameter.ParameterSets['Pagination'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Pagination'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Pagination'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FirstPages' { $parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['FirstPages'] $parameter.Name | Should -Be 'FirstPages' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Pagination' $parameter.ParameterSets.Keys | Should -Contain 'Pagination' $parameter.ParameterSets['Pagination'].IsMandatory | Should -Be $False $parameter.ParameterSets['Pagination'].Position | Should -Be -2147483648 $parameter.ParameterSets['Pagination'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Pagination'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Pagination'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FailOnErrorMessage' { $parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['FailOnErrorMessage'] $parameter.Name | Should -Be 'FailOnErrorMessage' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Get-D365LcsEnvironmentMetadata).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -ProjectId -BearerToken -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException #> } Describe "Testing parameterset SearchByEnvironmentId" { <# SearchByEnvironmentId - SearchByEnvironmentId -ProjectId -BearerToken -EnvironmentId -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException #> } Describe "Testing parameterset SearchByEnvironmentName" { <# SearchByEnvironmentName - SearchByEnvironmentName -ProjectId -BearerToken -EnvironmentName -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException #> } Describe "Testing parameterset Pagination" { <# Pagination - Pagination -ProjectId -BearerToken -TraverseAllPages -FirstPages -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365LcsEnvironmentRsatCertificate.Tests.ps1 ================================================ Describe "Get-D365LcsEnvironmentRsatCertificate Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365LcsEnvironmentRsatCertificate).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnvironmentId' { $parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['EnvironmentId'] $parameter.Name | Should -Be 'EnvironmentId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FailOnErrorMessage' { $parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['FailOnErrorMessage'] $parameter.Name | Should -Be 'FailOnErrorMessage' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Get-D365LcsEnvironmentRsatCertificate).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -EnvironmentId Default -ProjectId -BearerToken -EnvironmentId -OutputPath -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365LcsSharedAssetFile.Tests.ps1 ================================================ Describe "Get-D365LcsSharedAssetFile Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365LcsSharedAssetFile).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FileType' { $parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['FileType'] $parameter.Name | Should -Be 'FileType' $parameter.ParameterType.ToString() | Should -Be LcsAssetFileType $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AssetName' { $parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['AssetName'] $parameter.Name | Should -Be 'AssetName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AssetVersion' { $parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['AssetVersion'] $parameter.Name | Should -Be 'AssetVersion' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AssetFilename' { $parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['AssetFilename'] $parameter.Name | Should -Be 'AssetFilename' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AssetDescription' { $parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['AssetDescription'] $parameter.Name | Should -Be 'AssetDescription' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AssetId' { $parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['AssetId'] $parameter.Name | Should -Be 'AssetId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Latest' { $parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['Latest'] $parameter.Name | Should -Be 'Latest' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SkipSasGeneration' { $parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['SkipSasGeneration'] $parameter.Name | Should -Be 'SkipSasGeneration' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 9 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Get-D365LcsSharedAssetFile).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -ProjectId -FileType -AssetName -AssetVersion -AssetFilename -AssetDescription -AssetId -BearerToken -LcsApiUri -Latest -SkipSasGeneration -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365MaintenanceMode.Tests.ps1 ================================================ Describe "Get-D365MaintenanceMode Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365MaintenanceMode).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Get-D365MaintenanceMode).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 3 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Get-D365MaintenanceMode).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 4 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Get-D365MaintenanceMode).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 5 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Get-D365MaintenanceMode).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 6 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -DatabaseServer -DatabaseName -SqlUser -SqlPwd #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365Model.Tests.ps1 ================================================ Describe "Get-D365Model Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365Model).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365Model).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Module' { $parameter = (Get-Command Get-D365Model).Parameters['Module'] $parameter.Name | Should -Be 'Module' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter CustomizableOnly' { $parameter = (Get-Command Get-D365Model).Parameters['CustomizableOnly'] $parameter.Name | Should -Be 'CustomizableOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ExcludeMicrosoftModels' { $parameter = (Get-Command Get-D365Model).Parameters['ExcludeMicrosoftModels'] $parameter.Name | Should -Be 'ExcludeMicrosoftModels' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ExcludeBinaryModels' { $parameter = (Get-Command Get-D365Model).Parameters['ExcludeBinaryModels'] $parameter.Name | Should -Be 'ExcludeBinaryModels' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Get-D365Model).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Get-D365Model).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Name -Module -CustomizableOnly -ExcludeMicrosoftModels -ExcludeBinaryModels -BinDir -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365Module.Tests.ps1 ================================================ Describe "Get-D365Module Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365Module).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365Module).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ExcludeBinaryModules' { $parameter = (Get-Command Get-D365Module).Parameters['ExcludeBinaryModules'] $parameter.Name | Should -Be 'ExcludeBinaryModules' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter InDependencyOrder' { $parameter = (Get-Command Get-D365Module).Parameters['InDependencyOrder'] $parameter.Name | Should -Be 'InDependencyOrder' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Get-D365Module).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Get-D365Module).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Name -ExcludeBinaryModules -InDependencyOrder -BinDir -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365OfflineAuthenticationAdminEmail.Tests.ps1 ================================================ Describe "Get-D365OfflineAuthenticationAdminEmail Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365OfflineAuthenticationAdminEmail).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365PackageBundleDetail.Tests.ps1 ================================================ Describe "Get-D365PackageBundleDetail Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365PackageBundleDetail).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Get-D365PackageBundleDetail).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ExtractionPath' { $parameter = (Get-Command Get-D365PackageBundleDetail).Parameters['ExtractionPath'] $parameter.Name | Should -Be 'ExtractionPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter KB' { $parameter = (Get-Command Get-D365PackageBundleDetail).Parameters['KB'] $parameter.Name | Should -Be 'KB' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Hotfix' { $parameter = (Get-Command Get-D365PackageBundleDetail).Parameters['Hotfix'] $parameter.Name | Should -Be 'Hotfix' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Traverse' { $parameter = (Get-Command Get-D365PackageBundleDetail).Parameters['Traverse'] $parameter.Name | Should -Be 'Traverse' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter KeepFiles' { $parameter = (Get-Command Get-D365PackageBundleDetail).Parameters['KeepFiles'] $parameter.Name | Should -Be 'KeepFiles' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter IncludeRawManifest' { $parameter = (Get-Command Get-D365PackageBundleDetail).Parameters['IncludeRawManifest'] $parameter.Name | Should -Be 'IncludeRawManifest' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path __AllParameterSets -Path -ExtractionPath -KB -Hotfix -Traverse -KeepFiles -IncludeRawManifest #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365PackageLabelResourceFile.Tests.ps1 ================================================ Describe "Get-D365PackageLabelResourceFile Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365PackageLabelResourceFile).ParameterSets.Name | Should -Be 'Default', 'Specific' } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Get-D365PackageLabelResourceFile).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific', 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $True $parameter.ParameterSets['Specific'].Position | Should -Be -2147483648 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be -2147483648 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365PackageLabelResourceFile).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Language' { $parameter = (Get-Command Get-D365PackageLabelResourceFile).Parameters['Language'] $parameter.Name | Should -Be 'Language' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -PackageDirectory Default -PackageDirectory -Name -Language #> } Describe "Testing parameterset Specific" { <# Specific -PackageDirectory Specific -PackageDirectory -Name -Language #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365PackageLabelResources.Tests.ps1 ================================================ Describe "Get-D365PackageLabelResources Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365PackageLabelResources).ParameterSets.Name | Should -Be 'Default', 'Specific' } It 'Should have the expected parameter FilePath' { $parameter = (Get-Command Get-D365PackageLabelResources).Parameters['FilePath'] $parameter.Name | Should -Be 'FilePath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific', 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $True $parameter.ParameterSets['Specific'].Position | Should -Be -2147483648 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be -2147483648 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365PackageLabelResources).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Value' { $parameter = (Get-Command Get-D365PackageLabelResources).Parameters['Value'] $parameter.Name | Should -Be 'Value' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter IncludePath' { $parameter = (Get-Command Get-D365PackageLabelResources).Parameters['IncludePath'] $parameter.Name | Should -Be 'IncludePath' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -FilePath Default -FilePath -Name -Value -IncludePath #> } Describe "Testing parameterset Specific" { <# Specific -FilePath Specific -FilePath -Name -Value -IncludePath #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365ProductInformation.Tests.ps1 ================================================ Describe "Get-D365ProductInformation Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365ProductInformation).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365RsatCertificateThumbprint.Tests.ps1 ================================================ Describe "Get-D365RsatCertificateThumbprint Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365RsatCertificateThumbprint).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365RsatPlaybackFile.Tests.ps1 ================================================ Describe "Get-D365RsatPlaybackFile Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365RsatPlaybackFile).ParameterSets.Name | Should -Be 'Default', 'ExecutionUser' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Get-D365RsatPlaybackFile).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be -2147483648 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365RsatPlaybackFile).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ExecutionUsername' { $parameter = (Get-Command Get-D365RsatPlaybackFile).Parameters['ExecutionUsername'] $parameter.Name | Should -Be 'ExecutionUsername' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ExecutionUser' $parameter.ParameterSets.Keys | Should -Contain 'ExecutionUser' $parameter.ParameterSets['ExecutionUser'].IsMandatory | Should -Be $False $parameter.ParameterSets['ExecutionUser'].Position | Should -Be -2147483648 $parameter.ParameterSets['ExecutionUser'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ExecutionUser'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ExecutionUser'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -Path -Name #> } Describe "Testing parameterset ExecutionUser" { <# ExecutionUser - ExecutionUser -Name -ExecutionUsername #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365RsatSoapHostname.Tests.ps1 ================================================ Describe "Get-D365RsatSoapHostname Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365RsatSoapHostname).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365Runbook.Tests.ps1 ================================================ Describe "Get-D365Runbook Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365Runbook).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Get-D365Runbook).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365Runbook).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Latest' { $parameter = (Get-Command Get-D365Runbook).Parameters['Latest'] $parameter.Name | Should -Be 'Latest' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Path -Name -Latest #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365RunbookId.Tests.ps1 ================================================ Describe "Get-D365RunbookId Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365RunbookId).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Get-D365RunbookId).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path __AllParameterSets -Path #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365RunbookLogFile.Tests.ps1 ================================================ Describe "Get-D365RunbookLogFile Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365RunbookLogFile).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Get-D365RunbookLogFile).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Step' { $parameter = (Get-Command Get-D365RunbookLogFile).Parameters['Step'] $parameter.Name | Should -Be 'Step' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Latest' { $parameter = (Get-Command Get-D365RunbookLogFile).Parameters['Latest'] $parameter.Name | Should -Be 'Latest' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OpenInEditor' { $parameter = (Get-Command Get-D365RunbookLogFile).Parameters['OpenInEditor'] $parameter.Name | Should -Be 'OpenInEditor' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path -Step __AllParameterSets -Path -Step -Latest -OpenInEditor #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365SDPCleanUp.Tests.ps1 ================================================ Describe "Get-D365SDPCleanUp Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365SDPCleanUp).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365SDPDetails.Tests.ps1 ================================================ Describe "Get-D365SDPDetails Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365SDPDetails).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Get-D365SDPDetails).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path __AllParameterSets -Path #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365Table.Tests.ps1 ================================================ Describe "Get-D365Table Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365Table).ParameterSets.Name | Should -Be 'Default', 'TableId' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365Table).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Id' { $parameter = (Get-Command Get-D365Table).Parameters['Id'] $parameter.Name | Should -Be 'Id' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'TableId' $parameter.ParameterSets.Keys | Should -Contain 'TableId' $parameter.ParameterSets['TableId'].IsMandatory | Should -Be $True $parameter.ParameterSets['TableId'].Position | Should -Be 1 $parameter.ParameterSets['TableId'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['TableId'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['TableId'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Get-D365Table).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Get-D365Table).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Get-D365Table).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Get-D365Table).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -Name -DatabaseServer -DatabaseName -SqlUser -SqlPwd #> } Describe "Testing parameterset TableId" { <# TableId -Id TableId -Id -DatabaseServer -DatabaseName -SqlUser -SqlPwd #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365TableField.Tests.ps1 ================================================ Describe "Get-D365TableField Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365TableField).ParameterSets.Name | Should -Be 'Default', 'SearchByNameForce', 'TableName' } It 'Should have the expected parameter TableId' { $parameter = (Get-Command Get-D365TableField).Parameters['TableId'] $parameter.Name | Should -Be 'TableId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365TableField).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'SearchByNameForce', 'TableName', 'Default' $parameter.ParameterSets.Keys | Should -Contain 'SearchByNameForce' $parameter.ParameterSets['SearchByNameForce'].IsMandatory | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].Position | Should -Be 1 $parameter.ParameterSets['SearchByNameForce'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'TableName' $parameter.ParameterSets['TableName'].IsMandatory | Should -Be $False $parameter.ParameterSets['TableName'].Position | Should -Be 2 $parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 2 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FieldId' { $parameter = (Get-Command Get-D365TableField).Parameters['FieldId'] $parameter.Name | Should -Be 'FieldId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'TableName', 'Default' $parameter.ParameterSets.Keys | Should -Contain 'TableName' $parameter.ParameterSets['TableName'].IsMandatory | Should -Be $False $parameter.ParameterSets['TableName'].Position | Should -Be 3 $parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 3 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Get-D365TableField).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'SearchByNameForce', 'TableName', 'Default' $parameter.ParameterSets.Keys | Should -Contain 'SearchByNameForce' $parameter.ParameterSets['SearchByNameForce'].IsMandatory | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].Position | Should -Be 3 $parameter.ParameterSets['SearchByNameForce'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'TableName' $parameter.ParameterSets['TableName'].IsMandatory | Should -Be $False $parameter.ParameterSets['TableName'].Position | Should -Be 4 $parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 4 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Get-D365TableField).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'SearchByNameForce', 'TableName', 'Default' $parameter.ParameterSets.Keys | Should -Contain 'SearchByNameForce' $parameter.ParameterSets['SearchByNameForce'].IsMandatory | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].Position | Should -Be 4 $parameter.ParameterSets['SearchByNameForce'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'TableName' $parameter.ParameterSets['TableName'].IsMandatory | Should -Be $False $parameter.ParameterSets['TableName'].Position | Should -Be 5 $parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 5 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Get-D365TableField).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'SearchByNameForce', 'TableName', 'Default' $parameter.ParameterSets.Keys | Should -Contain 'SearchByNameForce' $parameter.ParameterSets['SearchByNameForce'].IsMandatory | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].Position | Should -Be 5 $parameter.ParameterSets['SearchByNameForce'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'TableName' $parameter.ParameterSets['TableName'].IsMandatory | Should -Be $False $parameter.ParameterSets['TableName'].Position | Should -Be 6 $parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 6 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Get-D365TableField).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'SearchByNameForce', 'TableName', 'Default' $parameter.ParameterSets.Keys | Should -Contain 'SearchByNameForce' $parameter.ParameterSets['SearchByNameForce'].IsMandatory | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].Position | Should -Be 6 $parameter.ParameterSets['SearchByNameForce'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'TableName' $parameter.ParameterSets['TableName'].IsMandatory | Should -Be $False $parameter.ParameterSets['TableName'].Position | Should -Be 7 $parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 7 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter TableName' { $parameter = (Get-Command Get-D365TableField).Parameters['TableName'] $parameter.Name | Should -Be 'TableName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'TableName' $parameter.ParameterSets.Keys | Should -Contain 'TableName' $parameter.ParameterSets['TableName'].IsMandatory | Should -Be $True $parameter.ParameterSets['TableName'].Position | Should -Be 1 $parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter IncludeTableDetails' { $parameter = (Get-Command Get-D365TableField).Parameters['IncludeTableDetails'] $parameter.Name | Should -Be 'IncludeTableDetails' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'TableName', 'Default' $parameter.ParameterSets.Keys | Should -Contain 'TableName' $parameter.ParameterSets['TableName'].IsMandatory | Should -Be $False $parameter.ParameterSets['TableName'].Position | Should -Be -2147483648 $parameter.ParameterSets['TableName'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['TableName'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['TableName'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be -2147483648 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SearchAcrossTables' { $parameter = (Get-Command Get-D365TableField).Parameters['SearchAcrossTables'] $parameter.Name | Should -Be 'SearchAcrossTables' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'SearchByNameForce' $parameter.ParameterSets.Keys | Should -Contain 'SearchByNameForce' $parameter.ParameterSets['SearchByNameForce'].IsMandatory | Should -Be $True $parameter.ParameterSets['SearchByNameForce'].Position | Should -Be 2 $parameter.ParameterSets['SearchByNameForce'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['SearchByNameForce'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -TableId Default -TableId -Name -FieldId -DatabaseServer -DatabaseName -SqlUser -SqlPwd -IncludeTableDetails #> } Describe "Testing parameterset SearchByNameForce" { <# SearchByNameForce -SearchAcrossTables SearchByNameForce -Name -DatabaseServer -DatabaseName -SqlUser -SqlPwd -SearchAcrossTables #> } Describe "Testing parameterset TableName" { <# TableName -TableName TableName -Name -FieldId -DatabaseServer -DatabaseName -SqlUser -SqlPwd -TableName -IncludeTableDetails #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365TableSequence.Tests.ps1 ================================================ Describe "Get-D365TableSequence Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365TableSequence).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter TableName' { $parameter = (Get-Command Get-D365TableSequence).Parameters['TableName'] $parameter.Name | Should -Be 'TableName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Get-D365TableSequence).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Get-D365TableSequence).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Get-D365TableSequence).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Get-D365TableSequence).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -TableName -DatabaseServer -DatabaseName -SqlUser -SqlPwd #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365TablesInChangedTracking.Tests.ps1 ================================================ Describe "Get-D365TablesInChangedTracking Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365TablesInChangedTracking).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Get-D365TablesInChangedTracking).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Get-D365TablesInChangedTracking).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Get-D365TablesInChangedTracking).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Get-D365TablesInChangedTracking).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Get-D365TablesInChangedTracking).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Name -DatabaseServer -DatabaseName -SqlUser -SqlPwd #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365TfsUri.Tests.ps1 ================================================ Describe "Get-D365TfsUri Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365TfsUri).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Get-D365TfsUri).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -Path #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365TfsWorkspace.Tests.ps1 ================================================ Describe "Get-D365TfsWorkspace Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365TfsWorkspace).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Get-D365TfsWorkspace).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter TfsUri' { $parameter = (Get-Command Get-D365TfsWorkspace).Parameters['TfsUri'] $parameter.Name | Should -Be 'TfsUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Path -TfsUri #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365Url.Tests.ps1 ================================================ Describe "Get-D365Url Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365Url).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Force' { $parameter = (Get-Command Get-D365Url).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365User.Tests.ps1 ================================================ Describe "Get-D365User Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365User).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Get-D365User).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Get-D365User).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Get-D365User).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Get-D365User).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Email' { $parameter = (Get-Command Get-D365User).Parameters['Email'] $parameter.Name | Should -Be 'Email' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ExcludeSystemUsers' { $parameter = (Get-Command Get-D365User).Parameters['ExcludeSystemUsers'] $parameter.Name | Should -Be 'ExcludeSystemUsers' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -Email -ExcludeSystemUsers #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365UserAuthenticationDetail.Tests.ps1 ================================================ Describe "Get-D365UserAuthenticationDetail Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365UserAuthenticationDetail).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Email' { $parameter = (Get-Command Get-D365UserAuthenticationDetail).Parameters['Email'] $parameter.Name | Should -Be 'Email' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Email __AllParameterSets -Email #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365VisualStudioCompilerResult.Tests.ps1 ================================================ Describe "Get-D365VisualStudioCompilerResult Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365VisualStudioCompilerResult).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Module' { $parameter = (Get-Command Get-D365VisualStudioCompilerResult).Parameters['Module'] $parameter.Name | Should -Be 'Module' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ErrorsOnly' { $parameter = (Get-Command Get-D365VisualStudioCompilerResult).Parameters['ErrorsOnly'] $parameter.Name | Should -Be 'ErrorsOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputTotals' { $parameter = (Get-Command Get-D365VisualStudioCompilerResult).Parameters['OutputTotals'] $parameter.Name | Should -Be 'OutputTotals' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputAsObjects' { $parameter = (Get-Command Get-D365VisualStudioCompilerResult).Parameters['OutputAsObjects'] $parameter.Name | Should -Be 'OutputAsObjects' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Get-D365VisualStudioCompilerResult).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Module -ErrorsOnly -OutputTotals -OutputAsObjects -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365WebServerType.Tests.ps1 ================================================ Describe "Get-D365WebServerType Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365WebServerType).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Get-D365WindowsActivationStatus.Tests.ps1 ================================================ Describe "Get-D365WindowsActivationStatus Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Get-D365WindowsActivationStatus).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Import-D365AadApplication.Tests.ps1 ================================================ Describe "Import-D365AadApplication Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Import-D365AadApplication).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Import-D365AadApplication).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter UserId' { $parameter = (Get-Command Import-D365AadApplication).Parameters['UserId'] $parameter.Name | Should -Be 'UserId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ClientId' { $parameter = (Get-Command Import-D365AadApplication).Parameters['ClientId'] $parameter.Name | Should -Be 'ClientId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Import-D365AadApplication).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Import-D365AadApplication).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Import-D365AadApplication).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Import-D365AadApplication).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Name -UserId -ClientId __AllParameterSets -Name -UserId -ClientId -DatabaseServer -DatabaseName -SqlUser -SqlPwd #> } } ================================================ FILE: d365fo.tools/tests/functions/Import-D365AadUser.Tests.ps1 ================================================ Describe "Import-D365AadUser Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Import-D365AadUser).ParameterSets.Name | Should -Be 'UserListImport', 'GroupNameImport', 'GroupIdImport' } It 'Should have the expected parameter AadGroupName' { $parameter = (Get-Command Import-D365AadUser).Parameters['AadGroupName'] $parameter.Name | Should -Be 'AadGroupName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'GroupNameImport' $parameter.ParameterSets.Keys | Should -Contain 'GroupNameImport' $parameter.ParameterSets['GroupNameImport'].IsMandatory | Should -Be $True $parameter.ParameterSets['GroupNameImport'].Position | Should -Be 1 $parameter.ParameterSets['GroupNameImport'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['GroupNameImport'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['GroupNameImport'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Users' { $parameter = (Get-Command Import-D365AadUser).Parameters['Users'] $parameter.Name | Should -Be 'Users' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'UserListImport' $parameter.ParameterSets.Keys | Should -Contain 'UserListImport' $parameter.ParameterSets['UserListImport'].IsMandatory | Should -Be $True $parameter.ParameterSets['UserListImport'].Position | Should -Be 1 $parameter.ParameterSets['UserListImport'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['UserListImport'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['UserListImport'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter StartupCompany' { $parameter = (Get-Command Import-D365AadUser).Parameters['StartupCompany'] $parameter.Name | Should -Be 'StartupCompany' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Import-D365AadUser).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Import-D365AadUser).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Import-D365AadUser).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Import-D365AadUser).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter IdPrefix' { $parameter = (Get-Command Import-D365AadUser).Parameters['IdPrefix'] $parameter.Name | Should -Be 'IdPrefix' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter NameSuffix' { $parameter = (Get-Command Import-D365AadUser).Parameters['NameSuffix'] $parameter.Name | Should -Be 'NameSuffix' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter IdValue' { $parameter = (Get-Command Import-D365AadUser).Parameters['IdValue'] $parameter.Name | Should -Be 'IdValue' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 9 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter NameValue' { $parameter = (Get-Command Import-D365AadUser).Parameters['NameValue'] $parameter.Name | Should -Be 'NameValue' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 10 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AzureAdCredential' { $parameter = (Get-Command Import-D365AadUser).Parameters['AzureAdCredential'] $parameter.Name | Should -Be 'AzureAdCredential' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.PSCredential $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 11 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SkipAzureAd' { $parameter = (Get-Command Import-D365AadUser).Parameters['SkipAzureAd'] $parameter.Name | Should -Be 'SkipAzureAd' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'UserListImport' $parameter.ParameterSets.Keys | Should -Contain 'UserListImport' $parameter.ParameterSets['UserListImport'].IsMandatory | Should -Be $False $parameter.ParameterSets['UserListImport'].Position | Should -Be 12 $parameter.ParameterSets['UserListImport'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['UserListImport'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['UserListImport'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ForceExactAadGroupName' { $parameter = (Get-Command Import-D365AadUser).Parameters['ForceExactAadGroupName'] $parameter.Name | Should -Be 'ForceExactAadGroupName' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'GroupNameImport' $parameter.ParameterSets.Keys | Should -Contain 'GroupNameImport' $parameter.ParameterSets['GroupNameImport'].IsMandatory | Should -Be $False $parameter.ParameterSets['GroupNameImport'].Position | Should -Be 13 $parameter.ParameterSets['GroupNameImport'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['GroupNameImport'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['GroupNameImport'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AadGroupId' { $parameter = (Get-Command Import-D365AadUser).Parameters['AadGroupId'] $parameter.Name | Should -Be 'AadGroupId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'GroupIdImport' $parameter.ParameterSets.Keys | Should -Contain 'GroupIdImport' $parameter.ParameterSets['GroupIdImport'].IsMandatory | Should -Be $True $parameter.ParameterSets['GroupIdImport'].Position | Should -Be 14 $parameter.ParameterSets['GroupIdImport'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['GroupIdImport'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['GroupIdImport'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EmailValue' { $parameter = (Get-Command Import-D365AadUser).Parameters['EmailValue'] $parameter.Name | Should -Be 'EmailValue' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 15 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter TenantId' { $parameter = (Get-Command Import-D365AadUser).Parameters['TenantId'] $parameter.Name | Should -Be 'TenantId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 16 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset UserListImport" { <# UserListImport -Users UserListImport -Users -StartupCompany -DatabaseServer -DatabaseName -SqlUser -SqlPwd -IdPrefix -NameSuffix -IdValue -NameValue -AzureAdCredential -SkipAzureAd -EmailValue -TenantId #> } Describe "Testing parameterset GroupNameImport" { <# GroupNameImport -AadGroupName GroupNameImport -AadGroupName -StartupCompany -DatabaseServer -DatabaseName -SqlUser -SqlPwd -IdPrefix -NameSuffix -IdValue -NameValue -AzureAdCredential -ForceExactAadGroupName -EmailValue -TenantId #> } Describe "Testing parameterset GroupIdImport" { <# GroupIdImport -AadGroupId GroupIdImport -StartupCompany -DatabaseServer -DatabaseName -SqlUser -SqlPwd -IdPrefix -NameSuffix -IdValue -NameValue -AzureAdCredential -AadGroupId -EmailValue -TenantId #> } } ================================================ FILE: d365fo.tools/tests/functions/Import-D365Bacpac.Tests.ps1 ================================================ Describe "Import-D365Bacpac Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Import-D365Bacpac).ParameterSets.Name | Should -Be 'ImportTier1', 'ImportOnlyTier2', 'ImportTier2' } It 'Should have the expected parameter ImportModeTier1' { $parameter = (Get-Command Import-D365Bacpac).Parameters['ImportModeTier1'] $parameter.Name | Should -Be 'ImportModeTier1' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ImportTier1' $parameter.ParameterSets.Keys | Should -Contain 'ImportTier1' $parameter.ParameterSets['ImportTier1'].IsMandatory | Should -Be $True $parameter.ParameterSets['ImportTier1'].Position | Should -Be 0 $parameter.ParameterSets['ImportTier1'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportTier1'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportTier1'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ImportModeTier2' { $parameter = (Get-Command Import-D365Bacpac).Parameters['ImportModeTier2'] $parameter.Name | Should -Be 'ImportModeTier2' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2' $parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2' $parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 0 $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'ImportTier2' $parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ImportTier2'].Position | Should -Be 0 $parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Import-D365Bacpac).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Import-D365Bacpac).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Import-D365Bacpac).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier1', 'ImportTier2', '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2' $parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 3 $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'ImportTier1' $parameter.ParameterSets['ImportTier1'].IsMandatory | Should -Be $False $parameter.ParameterSets['ImportTier1'].Position | Should -Be 3 $parameter.ParameterSets['ImportTier1'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportTier1'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportTier1'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'ImportTier2' $parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ImportTier2'].Position | Should -Be 3 $parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Import-D365Bacpac).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier1', 'ImportTier2', '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2' $parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 4 $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'ImportTier1' $parameter.ParameterSets['ImportTier1'].IsMandatory | Should -Be $False $parameter.ParameterSets['ImportTier1'].Position | Should -Be 4 $parameter.ParameterSets['ImportTier1'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportTier1'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportTier1'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'ImportTier2' $parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ImportTier2'].Position | Should -Be 4 $parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BacpacFile' { $parameter = (Get-Command Import-D365Bacpac).Parameters['BacpacFile'] $parameter.Name | Should -Be 'BacpacFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter NewDatabaseName' { $parameter = (Get-Command Import-D365Bacpac).Parameters['NewDatabaseName'] $parameter.Name | Should -Be 'NewDatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AxDeployExtUserPwd' { $parameter = (Get-Command Import-D365Bacpac).Parameters['AxDeployExtUserPwd'] $parameter.Name | Should -Be 'AxDeployExtUserPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2' $parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2' $parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 7 $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'ImportTier2' $parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ImportTier2'].Position | Should -Be 7 $parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AxDbAdminPwd' { $parameter = (Get-Command Import-D365Bacpac).Parameters['AxDbAdminPwd'] $parameter.Name | Should -Be 'AxDbAdminPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2' $parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2' $parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 8 $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'ImportTier2' $parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ImportTier2'].Position | Should -Be 8 $parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AxRuntimeUserPwd' { $parameter = (Get-Command Import-D365Bacpac).Parameters['AxRuntimeUserPwd'] $parameter.Name | Should -Be 'AxRuntimeUserPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2' $parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2' $parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 9 $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'ImportTier2' $parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ImportTier2'].Position | Should -Be 9 $parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AxMrRuntimeUserPwd' { $parameter = (Get-Command Import-D365Bacpac).Parameters['AxMrRuntimeUserPwd'] $parameter.Name | Should -Be 'AxMrRuntimeUserPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2' $parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2' $parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 10 $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'ImportTier2' $parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ImportTier2'].Position | Should -Be 10 $parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AxRetailRuntimeUserPwd' { $parameter = (Get-Command Import-D365Bacpac).Parameters['AxRetailRuntimeUserPwd'] $parameter.Name | Should -Be 'AxRetailRuntimeUserPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2' $parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2' $parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 11 $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'ImportTier2' $parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ImportTier2'].Position | Should -Be 11 $parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AxRetailDataSyncUserPwd' { $parameter = (Get-Command Import-D365Bacpac).Parameters['AxRetailDataSyncUserPwd'] $parameter.Name | Should -Be 'AxRetailDataSyncUserPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2' $parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2' $parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 12 $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'ImportTier2' $parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ImportTier2'].Position | Should -Be 12 $parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AxDbReadonlyUserPwd' { $parameter = (Get-Command Import-D365Bacpac).Parameters['AxDbReadonlyUserPwd'] $parameter.Name | Should -Be 'AxDbReadonlyUserPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier2' $parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2' $parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be 13 $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'ImportTier2' $parameter.ParameterSets['ImportTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ImportTier2'].Position | Should -Be 13 $parameter.ParameterSets['ImportTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportTier2'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['ImportTier2'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter CustomSqlFile' { $parameter = (Get-Command Import-D365Bacpac).Parameters['CustomSqlFile'] $parameter.Name | Should -Be 'CustomSqlFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ModelFile' { $parameter = (Get-Command Import-D365Bacpac).Parameters['ModelFile'] $parameter.Name | Should -Be 'ModelFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DiagnosticFile' { $parameter = (Get-Command Import-D365Bacpac).Parameters['DiagnosticFile'] $parameter.Name | Should -Be 'DiagnosticFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ImportOnly' { $parameter = (Get-Command Import-D365Bacpac).Parameters['ImportOnly'] $parameter.Name | Should -Be 'ImportOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ImportOnlyTier2', 'ImportTier1' $parameter.ParameterSets.Keys | Should -Contain 'ImportOnlyTier2' $parameter.ParameterSets['ImportOnlyTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ImportOnlyTier2'].Position | Should -Be -2147483648 $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportOnlyTier2'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'ImportTier1' $parameter.ParameterSets['ImportTier1'].IsMandatory | Should -Be $False $parameter.ParameterSets['ImportTier1'].Position | Should -Be -2147483648 $parameter.ParameterSets['ImportTier1'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportTier1'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportTier1'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MaxParallelism' { $parameter = (Get-Command Import-D365Bacpac).Parameters['MaxParallelism'] $parameter.Name | Should -Be 'MaxParallelism' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Import-D365Bacpac).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Import-D365Bacpac).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Import-D365Bacpac).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Import-D365Bacpac).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Properties' { $parameter = (Get-Command Import-D365Bacpac).Parameters['Properties'] $parameter.Name | Should -Be 'Properties' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset ImportTier1" { <# ImportTier1 -ImportModeTier1 -BacpacFile -NewDatabaseName ImportTier1 -ImportModeTier1 -DatabaseServer -DatabaseName -SqlUser -SqlPwd -BacpacFile -NewDatabaseName -CustomSqlFile -ModelFile -DiagnosticFile -ImportOnly -MaxParallelism -LogPath -ShowOriginalProgress -OutputCommandOnly -EnableException -Properties #> } Describe "Testing parameterset ImportOnlyTier2" { <# ImportOnlyTier2 -ImportModeTier2 -SqlUser -SqlPwd -BacpacFile -NewDatabaseName -ImportOnly ImportOnlyTier2 -ImportModeTier2 -DatabaseServer -DatabaseName -SqlUser -SqlPwd -BacpacFile -NewDatabaseName -AxDeployExtUserPwd -AxDbAdminPwd -AxRuntimeUserPwd -AxMrRuntimeUserPwd -AxRetailRuntimeUserPwd -AxRetailDataSyncUserPwd -AxDbReadonlyUserPwd -CustomSqlFile -ModelFile -DiagnosticFile -ImportOnly -MaxParallelism -LogPath -ShowOriginalProgress -OutputCommandOnly -EnableException -Properties #> } Describe "Testing parameterset ImportTier2" { <# ImportTier2 -ImportModeTier2 -SqlUser -SqlPwd -BacpacFile -NewDatabaseName -AxDeployExtUserPwd -AxDbAdminPwd -AxRuntimeUserPwd -AxMrRuntimeUserPwd -AxRetailRuntimeUserPwd -AxRetailDataSyncUserPwd -AxDbReadonlyUserPwd ImportTier2 -ImportModeTier2 -DatabaseServer -DatabaseName -SqlUser -SqlPwd -BacpacFile -NewDatabaseName -AxDeployExtUserPwd -AxDbAdminPwd -AxRuntimeUserPwd -AxMrRuntimeUserPwd -AxRetailRuntimeUserPwd -AxRetailDataSyncUserPwd -AxDbReadonlyUserPwd -CustomSqlFile -ModelFile -DiagnosticFile -MaxParallelism -LogPath -ShowOriginalProgress -OutputCommandOnly -EnableException -Properties #> } } ================================================ FILE: d365fo.tools/tests/functions/Import-D365Dacpac.Tests.ps1 ================================================ Describe "Import-D365Dacpac Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Import-D365Dacpac).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Import-D365Dacpac).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ModelFile' { $parameter = (Get-Command Import-D365Dacpac).Parameters['ModelFile'] $parameter.Name | Should -Be 'ModelFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PublishFile' { $parameter = (Get-Command Import-D365Dacpac).Parameters['PublishFile'] $parameter.Name | Should -Be 'PublishFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DiagnosticFile' { $parameter = (Get-Command Import-D365Dacpac).Parameters['DiagnosticFile'] $parameter.Name | Should -Be 'DiagnosticFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MaxParallelism' { $parameter = (Get-Command Import-D365Dacpac).Parameters['MaxParallelism'] $parameter.Name | Should -Be 'MaxParallelism' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Import-D365Dacpac).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Import-D365Dacpac).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Import-D365Dacpac).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Import-D365Dacpac).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Import-D365Dacpac).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 9 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Import-D365Dacpac).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Import-D365Dacpac).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Import-D365Dacpac).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path __AllParameterSets -Path -ModelFile -PublishFile -DiagnosticFile -MaxParallelism -DatabaseServer -DatabaseName -SqlUser -SqlPwd -LogPath -ShowOriginalProgress -OutputCommandOnly -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Import-D365ExternalUser.Tests.ps1 ================================================ Describe "Import-D365ExternalUser Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Import-D365ExternalUser).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Id' { $parameter = (Get-Command Import-D365ExternalUser).Parameters['Id'] $parameter.Name | Should -Be 'Id' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Import-D365ExternalUser).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Email' { $parameter = (Get-Command Import-D365ExternalUser).Parameters['Email'] $parameter.Name | Should -Be 'Email' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Enabled' { $parameter = (Get-Command Import-D365ExternalUser).Parameters['Enabled'] $parameter.Name | Should -Be 'Enabled' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Company' { $parameter = (Get-Command Import-D365ExternalUser).Parameters['Company'] $parameter.Name | Should -Be 'Company' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Language' { $parameter = (Get-Command Import-D365ExternalUser).Parameters['Language'] $parameter.Name | Should -Be 'Language' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Import-D365ExternalUser).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Import-D365ExternalUser).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Import-D365ExternalUser).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Import-D365ExternalUser).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 9 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Id -Name -Email __AllParameterSets -Id -Name -Email -Enabled -Company -Language -DatabaseServer -DatabaseName -SqlUser -SqlPwd #> } } ================================================ FILE: d365fo.tools/tests/functions/Import-D365Model.Tests.ps1 ================================================ Describe "Import-D365Model Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Import-D365Model).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Import-D365Model).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Import-D365Model).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Import-D365Model).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Replace' { $parameter = (Get-Command Import-D365Model).Parameters['Replace'] $parameter.Name | Should -Be 'Replace' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Import-D365Model).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Import-D365Model).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Import-D365Model).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path __AllParameterSets -Path -BinDir -MetaDataDir -Replace -LogPath -ShowOriginalProgress -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Import-D365RsatSelfServiceCertificates.Tests.ps1 ================================================ Describe "Import-D365RsatSelfServiceCertificates Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Import-D365RsatSelfServiceCertificates).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Import-D365RsatSelfServiceCertificates).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Password' { $parameter = (Get-Command Import-D365RsatSelfServiceCertificates).Parameters['Password'] $parameter.Name | Should -Be 'Password' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path -Password __AllParameterSets -Path -Password #> } } ================================================ FILE: d365fo.tools/tests/functions/Initialize-D365RsatCertificate.Tests.ps1 ================================================ Describe "Initialize-D365RsatCertificate Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Initialize-D365RsatCertificate).ParameterSets.Name | Should -Be 'KeepCertificateFile' } It 'Should have the expected parameter CertificateFileName' { $parameter = (Get-Command Initialize-D365RsatCertificate).Parameters['CertificateFileName'] $parameter.Name | Should -Be 'CertificateFileName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PrivateKeyFileName' { $parameter = (Get-Command Initialize-D365RsatCertificate).Parameters['PrivateKeyFileName'] $parameter.Name | Should -Be 'PrivateKeyFileName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Password' { $parameter = (Get-Command Initialize-D365RsatCertificate).Parameters['Password'] $parameter.Name | Should -Be 'Password' $parameter.ParameterType.ToString() | Should -Be System.Security.SecureString $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter CertificateOnly' { $parameter = (Get-Command Initialize-D365RsatCertificate).Parameters['CertificateOnly'] $parameter.Name | Should -Be 'CertificateOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter KeepCertificateFile' { $parameter = (Get-Command Initialize-D365RsatCertificate).Parameters['KeepCertificateFile'] $parameter.Name | Should -Be 'KeepCertificateFile' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'KeepCertificateFile' $parameter.ParameterSets.Keys | Should -Contain 'KeepCertificateFile' $parameter.ParameterSets['KeepCertificateFile'].IsMandatory | Should -Be $False $parameter.ParameterSets['KeepCertificateFile'].Position | Should -Be -2147483648 $parameter.ParameterSets['KeepCertificateFile'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['KeepCertificateFile'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['KeepCertificateFile'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Initialize-D365RsatCertificate).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'KeepCertificateFile' $parameter.ParameterSets.Keys | Should -Contain 'KeepCertificateFile' $parameter.ParameterSets['KeepCertificateFile'].IsMandatory | Should -Be $False $parameter.ParameterSets['KeepCertificateFile'].Position | Should -Be -2147483648 $parameter.ParameterSets['KeepCertificateFile'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['KeepCertificateFile'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['KeepCertificateFile'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset KeepCertificateFile" { <# KeepCertificateFile - KeepCertificateFile -CertificateFileName -PrivateKeyFileName -Password -CertificateOnly -KeepCertificateFile -OutputPath #> } } ================================================ FILE: d365fo.tools/tests/functions/Install-D365SupportingSoftware.Tests.ps1 ================================================ Describe "Install-D365SupportingSoftware Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Install-D365SupportingSoftware).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Install-D365SupportingSoftware).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Install-D365SupportingSoftware).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Name __AllParameterSets -Name -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365AzCopyTransfer.Tests.ps1 ================================================ Describe "Invoke-D365AzCopyTransfer Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365AzCopyTransfer).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter SourceUri' { $parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['SourceUri'] $parameter.Name | Should -Be 'SourceUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DestinationUri' { $parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['DestinationUri'] $parameter.Name | Should -Be 'DestinationUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FileName' { $parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['FileName'] $parameter.Name | Should -Be 'FileName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DeleteOnTransferComplete' { $parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['DeleteOnTransferComplete'] $parameter.Name | Should -Be 'DeleteOnTransferComplete' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Invoke-D365AzCopyTransfer).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -SourceUri -DestinationUri __AllParameterSets -SourceUri -DestinationUri -FileName -DeleteOnTransferComplete -LogPath -ShowOriginalProgress -OutputCommandOnly -Force -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365AzureDevOpsNugetPush.Tests.ps1 ================================================ Describe "Invoke-D365AzureDevOpsNugetPush Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365AzureDevOpsNugetPush).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Invoke-D365AzureDevOpsNugetPush).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Source' { $parameter = (Get-Command Invoke-D365AzureDevOpsNugetPush).Parameters['Source'] $parameter.Name | Should -Be 'Source' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Invoke-D365AzureDevOpsNugetPush).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Invoke-D365AzureDevOpsNugetPush).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Invoke-D365AzureDevOpsNugetPush).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Invoke-D365AzureDevOpsNugetPush).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Path -Source -LogPath -ShowOriginalProgress -OutputCommandOnly -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365AzureStorageDownload.Tests.ps1 ================================================ Describe "Invoke-D365AzureStorageDownload Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365AzureStorageDownload).ParameterSets.Name | Should -Be 'Default', 'Latest' } It 'Should have the expected parameter AccountId' { $parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['AccountId'] $parameter.Name | Should -Be 'AccountId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AccessToken' { $parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['AccessToken'] $parameter.Name | Should -Be 'AccessToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SAS' { $parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['SAS'] $parameter.Name | Should -Be 'SAS' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Container' { $parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['Container'] $parameter.Name | Should -Be 'Container' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FileName' { $parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['FileName'] $parameter.Name | Should -Be 'FileName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be -2147483648 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Path' { $parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Latest' { $parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['Latest'] $parameter.Name | Should -Be 'Latest' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Latest' $parameter.ParameterSets.Keys | Should -Contain 'Latest' $parameter.ParameterSets['Latest'].IsMandatory | Should -Be $True $parameter.ParameterSets['Latest'].Position | Should -Be 4 $parameter.ParameterSets['Latest'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Latest'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Latest'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Invoke-D365AzureStorageDownload).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -FileName Default -AccountId -AccessToken -SAS -Container -FileName -Path -Force -EnableException #> } Describe "Testing parameterset Latest" { <# Latest -Latest Latest -AccountId -AccessToken -SAS -Container -Path -Latest -Force -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365AzureStorageUpload.Tests.ps1 ================================================ Describe "Invoke-D365AzureStorageUpload Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365AzureStorageUpload).ParameterSets.Name | Should -Be 'Default', 'Pipeline' } It 'Should have the expected parameter AccountId' { $parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['AccountId'] $parameter.Name | Should -Be 'AccountId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AccessToken' { $parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['AccessToken'] $parameter.Name | Should -Be 'AccessToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SAS' { $parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['SAS'] $parameter.Name | Should -Be 'SAS' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Container' { $parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['Container'] $parameter.Name | Should -Be 'Container' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Filepath' { $parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['Filepath'] $parameter.Name | Should -Be 'Filepath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Pipeline', 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Pipeline' $parameter.ParameterSets['Pipeline'].IsMandatory | Should -Be $True $parameter.ParameterSets['Pipeline'].Position | Should -Be -2147483648 $parameter.ParameterSets['Pipeline'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Pipeline'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Pipeline'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be -2147483648 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ContentType' { $parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['ContentType'] $parameter.Name | Should -Be 'ContentType' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DeleteOnUpload' { $parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['DeleteOnUpload'] $parameter.Name | Should -Be 'DeleteOnUpload' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Invoke-D365AzureStorageUpload).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -Filepath Default -AccountId -AccessToken -SAS -Container -Filepath -ContentType -Force -DeleteOnUpload -EnableException #> } Describe "Testing parameterset Pipeline" { <# Pipeline -Filepath Pipeline -AccountId -AccessToken -SAS -Container -Filepath -ContentType -Force -DeleteOnUpload -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365BestPractice.Tests.ps1 ================================================ Describe "Invoke-D365BestPractice Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365BestPractice).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Module' { $parameter = (Get-Command Invoke-D365BestPractice).Parameters['Module'] $parameter.Name | Should -Be 'Module' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Model' { $parameter = (Get-Command Invoke-D365BestPractice).Parameters['Model'] $parameter.Name | Should -Be 'Model' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365BestPractice).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Invoke-D365BestPractice).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackagesRoot' { $parameter = (Get-Command Invoke-D365BestPractice).Parameters['PackagesRoot'] $parameter.Name | Should -Be 'PackagesRoot' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Invoke-D365BestPractice).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Invoke-D365BestPractice).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RunFixers' { $parameter = (Get-Command Invoke-D365BestPractice).Parameters['RunFixers'] $parameter.Name | Should -Be 'RunFixers' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Invoke-D365BestPractice).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Module -Model __AllParameterSets -Module -Model -BinDir -MetaDataDir -PackagesRoot -LogPath -ShowOriginalProgress -RunFixers -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365CompilerResultAnalyzer.Tests.ps1 ================================================ Describe "Invoke-D365CompilerResultAnalyzer Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365CompilerResultAnalyzer).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Invoke-D365CompilerResultAnalyzer).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Invoke-D365CompilerResultAnalyzer).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SkipWarnings' { $parameter = (Get-Command Invoke-D365CompilerResultAnalyzer).Parameters['SkipWarnings'] $parameter.Name | Should -Be 'SkipWarnings' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SkipTasks' { $parameter = (Get-Command Invoke-D365CompilerResultAnalyzer).Parameters['SkipTasks'] $parameter.Name | Should -Be 'SkipTasks' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Invoke-D365CompilerResultAnalyzer).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path __AllParameterSets -Path -OutputPath -SkipWarnings -SkipTasks -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365DBSync.Tests.ps1 ================================================ Describe "Invoke-D365DbSync Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365DbSync).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter BinDirTools' { $parameter = (Get-Command Invoke-D365DbSync).Parameters['BinDirTools'] $parameter.Name | Should -Be 'BinDirTools' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetadataDir' { $parameter = (Get-Command Invoke-D365DbSync).Parameters['MetadataDir'] $parameter.Name | Should -Be 'MetadataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SyncMode' { $parameter = (Get-Command Invoke-D365DbSync).Parameters['SyncMode'] $parameter.Name | Should -Be 'SyncMode' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Verbosity' { $parameter = (Get-Command Invoke-D365DbSync).Parameters['Verbosity'] $parameter.Name | Should -Be 'Verbosity' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Invoke-D365DbSync).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Invoke-D365DbSync).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Invoke-D365DbSync).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Invoke-D365DbSync).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Invoke-D365DbSync).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Invoke-D365DbSync).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Invoke-D365DbSync).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -BinDirTools -MetadataDir -SyncMode -Verbosity -DatabaseServer -DatabaseName -SqlUser -SqlPwd -LogPath -ShowOriginalProgress -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365DBSyncPartial.Tests.ps1 ================================================ Describe "Invoke-D365DbSyncPartial Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365DbSyncPartial).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter SyncList' { $parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['SyncList'] $parameter.Name | Should -Be 'SyncList' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SyncExtensionsList' { $parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['SyncExtensionsList'] $parameter.Name | Should -Be 'SyncExtensionsList' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SyncMode' { $parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['SyncMode'] $parameter.Name | Should -Be 'SyncMode' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Verbosity' { $parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['Verbosity'] $parameter.Name | Should -Be 'Verbosity' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDirTools' { $parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['BinDirTools'] $parameter.Name | Should -Be 'BinDirTools' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetadataDir' { $parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['MetadataDir'] $parameter.Name | Should -Be 'MetadataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 9 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 10 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Invoke-D365DbSyncPartial).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -SyncList -SyncExtensionsList -SyncMode -Verbosity -BinDirTools -MetadataDir -DatabaseServer -DatabaseName -SqlUser -SqlPwd -LogPath -ShowOriginalProgress -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365DataFlush.Tests.ps1 ================================================ Describe "Invoke-D365DataFlush Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365DataFlush).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Url' { $parameter = (Get-Command Invoke-D365DataFlush).Parameters['Url'] $parameter.Name | Should -Be 'Url' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Class' { $parameter = (Get-Command Invoke-D365DataFlush).Parameters['Class'] $parameter.Name | Should -Be 'Class' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Url -Class #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365DbSyncModule.Tests.ps1 ================================================ Describe "Invoke-D365DbSyncModule Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365DbSyncModule).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Module' { $parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['Module'] $parameter.Name | Should -Be 'Module' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Verbosity' { $parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['Verbosity'] $parameter.Name | Should -Be 'Verbosity' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDirTools' { $parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['BinDirTools'] $parameter.Name | Should -Be 'BinDirTools' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetadataDir' { $parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['MetadataDir'] $parameter.Name | Should -Be 'MetadataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Invoke-D365DbSyncModule).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Module __AllParameterSets -Module -Verbosity -BinDirTools -MetadataDir -DatabaseServer -DatabaseName -SqlUser -SqlPwd -LogPath -ShowOriginalProgress -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365GenerateReportAggregateDataEntity.Tests.ps1 ================================================ Describe "Invoke-D365GenerateReportAggregateDataEntity Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365GenerateReportAggregateDataEntity).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Invoke-D365GenerateReportAggregateDataEntity).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365GenerateReportAggregateDataEntity).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Invoke-D365GenerateReportAggregateDataEntity).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -BinDir -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365GenerateReportAggregateMeasure.Tests.ps1 ================================================ Describe "Invoke-D365GenerateReportAggregateMeasure Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365GenerateReportAggregateMeasure).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Invoke-D365GenerateReportAggregateMeasure).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365GenerateReportAggregateMeasure).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Invoke-D365GenerateReportAggregateMeasure).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -BinDir -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365GenerateReportConfigKey.Tests.ps1 ================================================ Describe "Invoke-D365GenerateReportConfigKey Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365GenerateReportConfigKey).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Invoke-D365GenerateReportConfigKey).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365GenerateReportConfigKey).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Invoke-D365GenerateReportConfigKey).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -BinDir -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365GenerateReportConfigKeyGroup.Tests.ps1 ================================================ Describe "Invoke-D365GenerateReportConfigKeyGroup Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365GenerateReportConfigKeyGroup).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Invoke-D365GenerateReportConfigKeyGroup).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365GenerateReportConfigKeyGroup).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Invoke-D365GenerateReportConfigKeyGroup).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -BinDir -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365GenerateReportDataEntity.Tests.ps1 ================================================ Describe "Invoke-D365GenerateReportDataEntity Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365GenerateReportDataEntity).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Invoke-D365GenerateReportDataEntity).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365GenerateReportDataEntity).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Invoke-D365GenerateReportDataEntity).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -BinDir -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365GenerateReportDataEntityField.Tests.ps1 ================================================ Describe "Invoke-D365GenerateReportDataEntityField Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365GenerateReportDataEntityField).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Invoke-D365GenerateReportDataEntityField).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365GenerateReportDataEntityField).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Invoke-D365GenerateReportDataEntityField).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -BinDir -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365GenerateReportKpi.Tests.ps1 ================================================ Describe "Invoke-D365GenerateReportKpi Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365GenerateReportKpi).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Invoke-D365GenerateReportKpi).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365GenerateReportKpi).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Invoke-D365GenerateReportKpi).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -BinDir -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365GenerateReportLicenseCode.Tests.ps1 ================================================ Describe "Invoke-D365GenerateReportLicenseCode Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365GenerateReportLicenseCode).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Invoke-D365GenerateReportLicenseCode).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365GenerateReportLicenseCode).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Invoke-D365GenerateReportLicenseCode).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -BinDir -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365GenerateReportMenuItem.Tests.ps1 ================================================ Describe "Invoke-D365GenerateReportMenuItem Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365GenerateReportMenuItem).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Invoke-D365GenerateReportMenuItem).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365GenerateReportMenuItem).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Invoke-D365GenerateReportMenuItem).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -BinDir -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365GenerateReportSsrs.Tests.ps1 ================================================ Describe "Invoke-D365GenerateReportSsrs Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365GenerateReportSsrs).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Invoke-D365GenerateReportSsrs).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365GenerateReportSsrs).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Invoke-D365GenerateReportSsrs).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -BinDir -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365GenerateReportTable.Tests.ps1 ================================================ Describe "Invoke-D365GenerateReportTable Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365GenerateReportTable).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Invoke-D365GenerateReportTable).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365GenerateReportTable).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Invoke-D365GenerateReportTable).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -BinDir -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365GenerateReportWorkflowType.Tests.ps1 ================================================ Describe "Invoke-D365GenerateReportWorkflowType Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365GenerateReportWorkflowType).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Invoke-D365GenerateReportWorkflowType).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365GenerateReportWorkflowType).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Invoke-D365GenerateReportWorkflowType).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -BinDir -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365GenerateReports.Tests.ps1 ================================================ Describe "Invoke-D365GenerateReports Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365GenerateReports).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Invoke-D365GenerateReports).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365GenerateReports).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Invoke-D365GenerateReports).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -OutputPath -BinDir -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365InstallAzCopy.Tests.ps1 ================================================ Describe "Invoke-D365InstallAzCopy Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365InstallAzCopy).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Url' { $parameter = (Get-Command Invoke-D365InstallAzCopy).Parameters['Url'] $parameter.Name | Should -Be 'Url' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Path' { $parameter = (Get-Command Invoke-D365InstallAzCopy).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Url -Path #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365InstallLicense.Tests.ps1 ================================================ Describe "Invoke-D365InstallLicense Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365InstallLicense).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Invoke-D365InstallLicense).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Invoke-D365InstallLicense).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Invoke-D365InstallLicense).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Invoke-D365InstallLicense).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Invoke-D365InstallLicense).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Invoke-D365InstallLicense).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365InstallLicense).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Invoke-D365InstallLicense).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Invoke-D365InstallLicense).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Invoke-D365InstallLicense).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path __AllParameterSets -Path -DatabaseServer -DatabaseName -SqlUser -SqlPwd -MetaDataDir -BinDir -LogPath -ShowOriginalProgress -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365InstallNuget.Tests.ps1 ================================================ Describe "Invoke-D365InstallNuget Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365InstallNuget).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Invoke-D365InstallNuget).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Url' { $parameter = (Get-Command Invoke-D365InstallNuget).Parameters['Url'] $parameter.Name | Should -Be 'Url' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Path -Url #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365InstallSqlPackage.Tests.ps1 ================================================ Describe "Invoke-D365InstallSqlPackage Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365InstallSqlPackage).ParameterSets.Name | Should -Be 'ImportUrl', 'ImportLatest' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Invoke-D365InstallSqlPackage).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ImportLatest', 'ImportUrl' $parameter.ParameterSets.Keys | Should -Contain 'ImportLatest' $parameter.ParameterSets['ImportLatest'].IsMandatory | Should -Be $False $parameter.ParameterSets['ImportLatest'].Position | Should -Be -2147483648 $parameter.ParameterSets['ImportLatest'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportLatest'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportLatest'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'ImportUrl' $parameter.ParameterSets['ImportUrl'].IsMandatory | Should -Be $False $parameter.ParameterSets['ImportUrl'].Position | Should -Be -2147483648 $parameter.ParameterSets['ImportUrl'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportUrl'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportUrl'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Latest' { $parameter = (Get-Command Invoke-D365InstallSqlPackage).Parameters['Latest'] $parameter.Name | Should -Be 'Latest' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ImportLatest' $parameter.ParameterSets.Keys | Should -Contain 'ImportLatest' $parameter.ParameterSets['ImportLatest'].IsMandatory | Should -Be $False $parameter.ParameterSets['ImportLatest'].Position | Should -Be -2147483648 $parameter.ParameterSets['ImportLatest'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportLatest'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportLatest'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Url' { $parameter = (Get-Command Invoke-D365InstallSqlPackage).Parameters['Url'] $parameter.Name | Should -Be 'Url' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ImportUrl' $parameter.ParameterSets.Keys | Should -Contain 'ImportUrl' $parameter.ParameterSets['ImportUrl'].IsMandatory | Should -Be $False $parameter.ParameterSets['ImportUrl'].Position | Should -Be -2147483648 $parameter.ParameterSets['ImportUrl'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ImportUrl'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ImportUrl'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset ImportUrl" { <# ImportUrl - ImportUrl -Path -Url #> } Describe "Testing parameterset ImportLatest" { <# ImportLatest - ImportLatest -Path -Latest #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365LcsApiRefreshToken.Tests.ps1 ================================================ Describe "Invoke-D365LcsApiRefreshToken Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365LcsApiRefreshToken).ParameterSets.Name | Should -Be 'Object', 'Simple' } It 'Should have the expected parameter ClientId' { $parameter = (Get-Command Invoke-D365LcsApiRefreshToken).Parameters['ClientId'] $parameter.Name | Should -Be 'ClientId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Object', 'Simple' $parameter.ParameterSets.Keys | Should -Contain 'Object' $parameter.ParameterSets['Object'].IsMandatory | Should -Be $True $parameter.ParameterSets['Object'].Position | Should -Be -2147483648 $parameter.ParameterSets['Object'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Object'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Object'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Simple' $parameter.ParameterSets['Simple'].IsMandatory | Should -Be $True $parameter.ParameterSets['Simple'].Position | Should -Be -2147483648 $parameter.ParameterSets['Simple'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Simple'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Simple'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RefreshToken' { $parameter = (Get-Command Invoke-D365LcsApiRefreshToken).Parameters['RefreshToken'] $parameter.Name | Should -Be 'RefreshToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Simple' $parameter.ParameterSets.Keys | Should -Contain 'Simple' $parameter.ParameterSets['Simple'].IsMandatory | Should -Be $True $parameter.ParameterSets['Simple'].Position | Should -Be -2147483648 $parameter.ParameterSets['Simple'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Simple'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Simple'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter InputObject' { $parameter = (Get-Command Invoke-D365LcsApiRefreshToken).Parameters['InputObject'] $parameter.Name | Should -Be 'InputObject' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.PSObject $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Object' $parameter.ParameterSets.Keys | Should -Contain 'Object' $parameter.ParameterSets['Object'].IsMandatory | Should -Be $False $parameter.ParameterSets['Object'].Position | Should -Be -2147483648 $parameter.ParameterSets['Object'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Object'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Object'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Invoke-D365LcsApiRefreshToken).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Object" { <# Object -ClientId Object -ClientId -InputObject -EnableException #> } Describe "Testing parameterset Simple" { <# Simple -ClientId -RefreshToken Simple -ClientId -RefreshToken -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365LcsDatabaseExport.Tests.ps1 ================================================ Describe "Invoke-D365LcsDatabaseExport Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365LcsDatabaseExport).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SourceEnvironmentId' { $parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['SourceEnvironmentId'] $parameter.Name | Should -Be 'SourceEnvironmentId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BackupName' { $parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['BackupName'] $parameter.Name | Should -Be 'BackupName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SkipInitialStatusFetch' { $parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['SkipInitialStatusFetch'] $parameter.Name | Should -Be 'SkipInitialStatusFetch' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FailOnErrorMessage' { $parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['FailOnErrorMessage'] $parameter.Name | Should -Be 'FailOnErrorMessage' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Invoke-D365LcsDatabaseExport).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -SourceEnvironmentId -BackupName __AllParameterSets -ProjectId -BearerToken -SourceEnvironmentId -BackupName -LcsApiUri -SkipInitialStatusFetch -FailOnErrorMessage -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365LcsDatabaseRefresh.Tests.ps1 ================================================ Describe "Invoke-D365LcsDatabaseRefresh Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365LcsDatabaseRefresh).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SourceEnvironmentId' { $parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['SourceEnvironmentId'] $parameter.Name | Should -Be 'SourceEnvironmentId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter TargetEnvironmentId' { $parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['TargetEnvironmentId'] $parameter.Name | Should -Be 'TargetEnvironmentId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SkipInitialStatusFetch' { $parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['SkipInitialStatusFetch'] $parameter.Name | Should -Be 'SkipInitialStatusFetch' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FailOnErrorMessage' { $parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['FailOnErrorMessage'] $parameter.Name | Should -Be 'FailOnErrorMessage' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Invoke-D365LcsDatabaseRefresh).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -SourceEnvironmentId -TargetEnvironmentId __AllParameterSets -ProjectId -BearerToken -SourceEnvironmentId -TargetEnvironmentId -LcsApiUri -SkipInitialStatusFetch -FailOnErrorMessage -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365LcsDeployment.Tests.ps1 ================================================ Describe "Invoke-D365LcsDeployment Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365LcsDeployment).ParameterSets.Name | Should -Be 'VM', 'Self-Service' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AssetId' { $parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['AssetId'] $parameter.Name | Should -Be 'AssetId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnvironmentId' { $parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['EnvironmentId'] $parameter.Name | Should -Be 'EnvironmentId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter UpdateName' { $parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['UpdateName'] $parameter.Name | Should -Be 'UpdateName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Self-Service' $parameter.ParameterSets.Keys | Should -Contain 'Self-Service' $parameter.ParameterSets['Self-Service'].IsMandatory | Should -Be $True $parameter.ParameterSets['Self-Service'].Position | Should -Be -2147483648 $parameter.ParameterSets['Self-Service'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Self-Service'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Self-Service'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FailOnErrorMessage' { $parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['FailOnErrorMessage'] $parameter.Name | Should -Be 'FailOnErrorMessage' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Invoke-D365LcsDeployment).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset VM" { <# VM -AssetId -EnvironmentId VM -ProjectId -AssetId -EnvironmentId -BearerToken -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException #> } Describe "Testing parameterset Self-Service" { <# Self-Service -AssetId -EnvironmentId -UpdateName Self-Service -ProjectId -AssetId -EnvironmentId -UpdateName -BearerToken -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365LcsEnvironmentStart.Tests.ps1 ================================================ Describe "Invoke-D365LcsEnvironmentStart Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365LcsEnvironmentStart).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Invoke-D365LcsEnvironmentStart).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Invoke-D365LcsEnvironmentStart).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnvironmentId' { $parameter = (Get-Command Invoke-D365LcsEnvironmentStart).Parameters['EnvironmentId'] $parameter.Name | Should -Be 'EnvironmentId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Invoke-D365LcsEnvironmentStart).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FailOnErrorMessage' { $parameter = (Get-Command Invoke-D365LcsEnvironmentStart).Parameters['FailOnErrorMessage'] $parameter.Name | Should -Be 'FailOnErrorMessage' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Invoke-D365LcsEnvironmentStart).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Invoke-D365LcsEnvironmentStart).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -EnvironmentId __AllParameterSets -ProjectId -BearerToken -EnvironmentId -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365LcsEnvironmentStop.Tests.ps1 ================================================ Describe "Invoke-D365LcsEnvironmentStop Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365LcsEnvironmentStop).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Invoke-D365LcsEnvironmentStop).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Invoke-D365LcsEnvironmentStop).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnvironmentId' { $parameter = (Get-Command Invoke-D365LcsEnvironmentStop).Parameters['EnvironmentId'] $parameter.Name | Should -Be 'EnvironmentId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Invoke-D365LcsEnvironmentStop).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FailOnErrorMessage' { $parameter = (Get-Command Invoke-D365LcsEnvironmentStop).Parameters['FailOnErrorMessage'] $parameter.Name | Should -Be 'FailOnErrorMessage' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Invoke-D365LcsEnvironmentStop).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Invoke-D365LcsEnvironmentStop).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -EnvironmentId __AllParameterSets -ProjectId -BearerToken -EnvironmentId -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365LcsUpload.Tests.ps1 ================================================ Describe "Invoke-D365LcsUpload Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365LcsUpload).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Invoke-D365LcsUpload).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Invoke-D365LcsUpload).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FilePath' { $parameter = (Get-Command Invoke-D365LcsUpload).Parameters['FilePath'] $parameter.Name | Should -Be 'FilePath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FileType' { $parameter = (Get-Command Invoke-D365LcsUpload).Parameters['FileType'] $parameter.Name | Should -Be 'FileType' $parameter.ParameterType.ToString() | Should -Be LcsAssetFileType $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Name' { $parameter = (Get-Command Invoke-D365LcsUpload).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Filename' { $parameter = (Get-Command Invoke-D365LcsUpload).Parameters['Filename'] $parameter.Name | Should -Be 'Filename' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FileDescription' { $parameter = (Get-Command Invoke-D365LcsUpload).Parameters['FileDescription'] $parameter.Name | Should -Be 'FileDescription' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Invoke-D365LcsUpload).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FailOnErrorMessage' { $parameter = (Get-Command Invoke-D365LcsUpload).Parameters['FailOnErrorMessage'] $parameter.Name | Should -Be 'FailOnErrorMessage' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Invoke-D365LcsUpload).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Invoke-D365LcsUpload).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -FilePath __AllParameterSets -ProjectId -BearerToken -FilePath -FileType -Name -Filename -FileDescription -LcsApiUri -FailOnErrorMessage -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365ModuleCompile.Tests.ps1 ================================================ Describe "Invoke-D365ModuleCompile Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365ModuleCompile).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Module' { $parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['Module'] $parameter.Name | Should -Be 'Module' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputDir' { $parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['OutputDir'] $parameter.Name | Should -Be 'OutputDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ReferenceDir' { $parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['ReferenceDir'] $parameter.Name | Should -Be 'ReferenceDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter XRefSqlServer' { $parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['XRefSqlServer'] $parameter.Name | Should -Be 'XRefSqlServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter XRefDbName' { $parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['XRefDbName'] $parameter.Name | Should -Be 'XRefDbName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter XRefGeneration' { $parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['XRefGeneration'] $parameter.Name | Should -Be 'XRefGeneration' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter XRefGenerationOnly' { $parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['XRefGenerationOnly'] $parameter.Name | Should -Be 'XRefGenerationOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Invoke-D365ModuleCompile).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Module __AllParameterSets -Module -OutputDir -LogPath -MetaDataDir -ReferenceDir -BinDir -XRefSqlServer -XRefDbName -XRefGeneration -XRefGenerationOnly -ShowOriginalProgress -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365ModuleFullCompile.Tests.ps1 ================================================ Describe "Invoke-D365ModuleFullCompile Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365ModuleFullCompile).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Module' { $parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['Module'] $parameter.Name | Should -Be 'Module' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputDir' { $parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['OutputDir'] $parameter.Name | Should -Be 'OutputDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ReferenceDir' { $parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['ReferenceDir'] $parameter.Name | Should -Be 'ReferenceDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Invoke-D365ModuleFullCompile).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Module __AllParameterSets -Module -OutputDir -LogPath -MetaDataDir -ReferenceDir -BinDir -ShowOriginalProgress -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365ModuleLabelGeneration.Tests.ps1 ================================================ Describe "Invoke-D365ModuleLabelGeneration Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365ModuleLabelGeneration).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Module' { $parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['Module'] $parameter.Name | Should -Be 'Module' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputDir' { $parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['OutputDir'] $parameter.Name | Should -Be 'OutputDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ReferenceDir' { $parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['ReferenceDir'] $parameter.Name | Should -Be 'ReferenceDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Invoke-D365ModuleLabelGeneration).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Module __AllParameterSets -Module -OutputDir -LogPath -MetaDataDir -ReferenceDir -BinDir -ShowOriginalProgress -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365ModuleReportsCompile.Tests.ps1 ================================================ Describe "Invoke-D365ModuleReportsCompile Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365ModuleReportsCompile).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Module' { $parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['Module'] $parameter.Name | Should -Be 'Module' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputDir' { $parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['OutputDir'] $parameter.Name | Should -Be 'OutputDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ReferenceDir' { $parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['ReferenceDir'] $parameter.Name | Should -Be 'ReferenceDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Invoke-D365ModuleReportsCompile).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Module __AllParameterSets -Module -OutputDir -LogPath -MetaDataDir -ReferenceDir -BinDir -ShowOriginalProgress -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365ProcessModule.Tests.ps1 ================================================ Describe "Invoke-D365ProcessModule Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365ProcessModule).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Module' { $parameter = (Get-Command Invoke-D365ProcessModule).Parameters['Module'] $parameter.Name | Should -Be 'Module' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ExecuteCompile' { $parameter = (Get-Command Invoke-D365ProcessModule).Parameters['ExecuteCompile'] $parameter.Name | Should -Be 'ExecuteCompile' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ExecuteSync' { $parameter = (Get-Command Invoke-D365ProcessModule).Parameters['ExecuteSync'] $parameter.Name | Should -Be 'ExecuteSync' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ExecuteDeployReports' { $parameter = (Get-Command Invoke-D365ProcessModule).Parameters['ExecuteDeployReports'] $parameter.Name | Should -Be 'ExecuteDeployReports' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputDir' { $parameter = (Get-Command Invoke-D365ProcessModule).Parameters['OutputDir'] $parameter.Name | Should -Be 'OutputDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Invoke-D365ProcessModule).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Invoke-D365ProcessModule).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ReferenceDir' { $parameter = (Get-Command Invoke-D365ProcessModule).Parameters['ReferenceDir'] $parameter.Name | Should -Be 'ReferenceDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Invoke-D365ProcessModule).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Invoke-D365ProcessModule).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Invoke-D365ProcessModule).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Module __AllParameterSets -Module -ExecuteCompile -ExecuteSync -ExecuteDeployReports -OutputDir -LogPath -MetaDataDir -ReferenceDir -BinDir -ShowOriginalProgress -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365ReArmWindows.Tests.ps1 ================================================ Describe "Invoke-D365ReArmWindows Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365ReArmWindows).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Restart' { $parameter = (Get-Command Invoke-D365ReArmWindows).Parameters['Restart'] $parameter.Name | Should -Be 'Restart' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Restart #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365RunbookAnalyzer.Tests.ps1 ================================================ Describe "Invoke-D365RunbookAnalyzer Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365RunbookAnalyzer).ParameterSets.Name | Should -Be 'Default', 'FailedOnlyAsObjects', 'FailedOnly' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Invoke-D365RunbookAnalyzer).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'FailedOnlyAsObjects', 'FailedOnly', 'Default' $parameter.ParameterSets.Keys | Should -Contain 'FailedOnlyAsObjects' $parameter.ParameterSets['FailedOnlyAsObjects'].IsMandatory | Should -Be $True $parameter.ParameterSets['FailedOnlyAsObjects'].Position | Should -Be -2147483648 $parameter.ParameterSets['FailedOnlyAsObjects'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['FailedOnlyAsObjects'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['FailedOnlyAsObjects'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'FailedOnly' $parameter.ParameterSets['FailedOnly'].IsMandatory | Should -Be $True $parameter.ParameterSets['FailedOnly'].Position | Should -Be -2147483648 $parameter.ParameterSets['FailedOnly'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['FailedOnly'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['FailedOnly'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be -2147483648 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FailedOnly' { $parameter = (Get-Command Invoke-D365RunbookAnalyzer).Parameters['FailedOnly'] $parameter.Name | Should -Be 'FailedOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'FailedOnly' $parameter.ParameterSets.Keys | Should -Contain 'FailedOnly' $parameter.ParameterSets['FailedOnly'].IsMandatory | Should -Be $False $parameter.ParameterSets['FailedOnly'].Position | Should -Be -2147483648 $parameter.ParameterSets['FailedOnly'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['FailedOnly'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['FailedOnly'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FailedOnlyAsObjects' { $parameter = (Get-Command Invoke-D365RunbookAnalyzer).Parameters['FailedOnlyAsObjects'] $parameter.Name | Should -Be 'FailedOnlyAsObjects' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'FailedOnlyAsObjects' $parameter.ParameterSets.Keys | Should -Contain 'FailedOnlyAsObjects' $parameter.ParameterSets['FailedOnlyAsObjects'].IsMandatory | Should -Be $False $parameter.ParameterSets['FailedOnlyAsObjects'].Position | Should -Be -2147483648 $parameter.ParameterSets['FailedOnlyAsObjects'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['FailedOnlyAsObjects'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['FailedOnlyAsObjects'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -Path Default -Path #> } Describe "Testing parameterset FailedOnlyAsObjects" { <# FailedOnlyAsObjects -Path FailedOnlyAsObjects -Path -FailedOnlyAsObjects #> } Describe "Testing parameterset FailedOnly" { <# FailedOnly -Path FailedOnly -Path -FailedOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365SCDPBundleInstall.Tests.ps1 ================================================ Describe "Invoke-D365SCDPBundleInstall Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365SCDPBundleInstall).ParameterSets.Name | Should -Be 'InstallOnly', 'Tfs' } It 'Should have the expected parameter InstallOnly' { $parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['InstallOnly'] $parameter.Name | Should -Be 'InstallOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'InstallOnly' $parameter.ParameterSets.Keys | Should -Contain 'InstallOnly' $parameter.ParameterSets['InstallOnly'].IsMandatory | Should -Be $True $parameter.ParameterSets['InstallOnly'].Position | Should -Be 0 $parameter.ParameterSets['InstallOnly'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['InstallOnly'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['InstallOnly'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Command' { $parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['Command'] $parameter.Name | Should -Be 'Command' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Tfs' $parameter.ParameterSets.Keys | Should -Contain 'Tfs' $parameter.ParameterSets['Tfs'].IsMandatory | Should -Be $False $parameter.ParameterSets['Tfs'].Position | Should -Be 0 $parameter.ParameterSets['Tfs'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Tfs'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Tfs'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Path' { $parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter TfsWorkspaceDir' { $parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['TfsWorkspaceDir'] $parameter.Name | Should -Be 'TfsWorkspaceDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Tfs' $parameter.ParameterSets.Keys | Should -Contain 'Tfs' $parameter.ParameterSets['Tfs'].IsMandatory | Should -Be $False $parameter.ParameterSets['Tfs'].Position | Should -Be 3 $parameter.ParameterSets['Tfs'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Tfs'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Tfs'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter TfsUri' { $parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['TfsUri'] $parameter.Name | Should -Be 'TfsUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Tfs' $parameter.ParameterSets.Keys | Should -Contain 'Tfs' $parameter.ParameterSets['Tfs'].IsMandatory | Should -Be $False $parameter.ParameterSets['Tfs'].Position | Should -Be 4 $parameter.ParameterSets['Tfs'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Tfs'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Tfs'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowModifiedFiles' { $parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['ShowModifiedFiles'] $parameter.Name | Should -Be 'ShowModifiedFiles' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowProgress' { $parameter = (Get-Command Invoke-D365SCDPBundleInstall).Parameters['ShowProgress'] $parameter.Name | Should -Be 'ShowProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset InstallOnly" { <# InstallOnly -InstallOnly -Path InstallOnly -InstallOnly -Path -MetaDataDir -ShowModifiedFiles -ShowProgress #> } Describe "Testing parameterset Tfs" { <# Tfs -Path Tfs -Command -Path -MetaDataDir -TfsWorkspaceDir -TfsUri -ShowModifiedFiles -ShowProgress #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365SDPInstall.Tests.ps1 ================================================ Describe "Invoke-D365SDPInstall Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365SDPInstall).ParameterSets.Name | Should -Be 'QuickInstall', 'DevInstall', 'Manual', 'UDEInstall' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter QuickInstallAll' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['QuickInstallAll'] $parameter.Name | Should -Be 'QuickInstallAll' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'QuickInstall' $parameter.ParameterSets.Keys | Should -Contain 'QuickInstall' $parameter.ParameterSets['QuickInstall'].IsMandatory | Should -Be $False $parameter.ParameterSets['QuickInstall'].Position | Should -Be 3 $parameter.ParameterSets['QuickInstall'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['QuickInstall'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['QuickInstall'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DevInstall' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['DevInstall'] $parameter.Name | Should -Be 'DevInstall' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'DevInstall' $parameter.ParameterSets.Keys | Should -Contain 'DevInstall' $parameter.ParameterSets['DevInstall'].IsMandatory | Should -Be $False $parameter.ParameterSets['DevInstall'].Position | Should -Be 3 $parameter.ParameterSets['DevInstall'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['DevInstall'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['DevInstall'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Command' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['Command'] $parameter.Name | Should -Be 'Command' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Manual' $parameter.ParameterSets.Keys | Should -Contain 'Manual' $parameter.ParameterSets['Manual'].IsMandatory | Should -Be $True $parameter.ParameterSets['Manual'].Position | Should -Be 3 $parameter.ParameterSets['Manual'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Manual'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Manual'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Step' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['Step'] $parameter.Name | Should -Be 'Step' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RunbookId' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['RunbookId'] $parameter.Name | Should -Be 'RunbookId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter TopologyFile' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['TopologyFile'] $parameter.Name | Should -Be 'TopologyFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter UseExistingTopologyFile' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['UseExistingTopologyFile'] $parameter.Name | Should -Be 'UseExistingTopologyFile' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter UnifiedDevelopmentEnvironment' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['UnifiedDevelopmentEnvironment'] $parameter.Name | Should -Be 'UnifiedDevelopmentEnvironment' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'UDEInstall' $parameter.ParameterSets.Keys | Should -Contain 'UDEInstall' $parameter.ParameterSets['UDEInstall'].IsMandatory | Should -Be $False $parameter.ParameterSets['UDEInstall'].Position | Should -Be -2147483648 $parameter.ParameterSets['UDEInstall'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['UDEInstall'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['UDEInstall'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter IncludeFallbackRetailServiceModels' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['IncludeFallbackRetailServiceModels'] $parameter.Name | Should -Be 'IncludeFallbackRetailServiceModels' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ForceFallbackServiceModels' { $parameter = (Get-Command Invoke-D365SDPInstall).Parameters['ForceFallbackServiceModels'] $parameter.Name | Should -Be 'ForceFallbackServiceModels' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset QuickInstall" { <# QuickInstall -Path QuickInstall -Path -MetaDataDir -QuickInstallAll -Step -RunbookId -LogPath -ShowOriginalProgress -OutputCommandOnly -TopologyFile -UseExistingTopologyFile -IncludeFallbackRetailServiceModels -Force -ForceFallbackServiceModels #> } Describe "Testing parameterset DevInstall" { <# DevInstall -Path DevInstall -Path -MetaDataDir -DevInstall -Step -RunbookId -LogPath -ShowOriginalProgress -OutputCommandOnly -TopologyFile -UseExistingTopologyFile -IncludeFallbackRetailServiceModels -Force -ForceFallbackServiceModels #> } Describe "Testing parameterset Manual" { <# Manual -Path -Command Manual -Path -MetaDataDir -Command -Step -RunbookId -LogPath -ShowOriginalProgress -OutputCommandOnly -TopologyFile -UseExistingTopologyFile -IncludeFallbackRetailServiceModels -Force -ForceFallbackServiceModels #> } Describe "Testing parameterset UDEInstall" { <# UDEInstall -Path UDEInstall -Path -MetaDataDir -Step -RunbookId -LogPath -ShowOriginalProgress -OutputCommandOnly -TopologyFile -UseExistingTopologyFile -UnifiedDevelopmentEnvironment -IncludeFallbackRetailServiceModels -Force -ForceFallbackServiceModels #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365SDPInstallUDE.Tests.ps1 ================================================ Describe "Invoke-D365SDPInstallUDE Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365SDPInstallUDE).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Invoke-D365SDPInstallUDE).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Invoke-D365SDPInstallUDE).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Invoke-D365SDPInstallUDE).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Invoke-D365SDPInstallUDE).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path -MetaDataDir __AllParameterSets -Path -MetaDataDir -LogPath -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365SeleniumDownload.Tests.ps1 ================================================ Describe "Invoke-D365SeleniumDownload Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365SeleniumDownload).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter RegressionSuiteAutomationTool' { $parameter = (Get-Command Invoke-D365SeleniumDownload).Parameters['RegressionSuiteAutomationTool'] $parameter.Name | Should -Be 'RegressionSuiteAutomationTool' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PerfSDK' { $parameter = (Get-Command Invoke-D365SeleniumDownload).Parameters['PerfSDK'] $parameter.Name | Should -Be 'PerfSDK' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -RegressionSuiteAutomationTool -PerfSDK #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365SqlScript.Tests.ps1 ================================================ Describe "Invoke-D365SqlScript Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365SqlScript).ParameterSets.Name | Should -Be 'FilePath', 'Command' } It 'Should have the expected parameter FilePath' { $parameter = (Get-Command Invoke-D365SqlScript).Parameters['FilePath'] $parameter.Name | Should -Be 'FilePath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'FilePath' $parameter.ParameterSets.Keys | Should -Contain 'FilePath' $parameter.ParameterSets['FilePath'].IsMandatory | Should -Be $True $parameter.ParameterSets['FilePath'].Position | Should -Be 1 $parameter.ParameterSets['FilePath'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['FilePath'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['FilePath'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Command' { $parameter = (Get-Command Invoke-D365SqlScript).Parameters['Command'] $parameter.Name | Should -Be 'Command' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Command' $parameter.ParameterSets.Keys | Should -Contain 'Command' $parameter.ParameterSets['Command'].IsMandatory | Should -Be $True $parameter.ParameterSets['Command'].Position | Should -Be 1 $parameter.ParameterSets['Command'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Command'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Command'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Invoke-D365SqlScript).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Invoke-D365SqlScript).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Invoke-D365SqlScript).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Invoke-D365SqlScript).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter TrustedConnection' { $parameter = (Get-Command Invoke-D365SqlScript).Parameters['TrustedConnection'] $parameter.Name | Should -Be 'TrustedConnection' $parameter.ParameterType.ToString() | Should -Be System.Boolean $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Invoke-D365SqlScript).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter NoPooling' { $parameter = (Get-Command Invoke-D365SqlScript).Parameters['NoPooling'] $parameter.Name | Should -Be 'NoPooling' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset FilePath" { <# FilePath -FilePath FilePath -FilePath -DatabaseServer -DatabaseName -SqlUser -SqlPwd -TrustedConnection -EnableException -NoPooling #> } Describe "Testing parameterset Command" { <# Command -Command Command -Command -DatabaseServer -DatabaseName -SqlUser -SqlPwd -TrustedConnection -EnableException -NoPooling #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365SysFlushAodCache.Tests.ps1 ================================================ Describe "Invoke-D365SysFlushAodCache Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365SysFlushAodCache).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Url' { $parameter = (Get-Command Invoke-D365SysFlushAodCache).Parameters['Url'] $parameter.Name | Should -Be 'Url' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Url #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365SysRunnerClass.Tests.ps1 ================================================ Describe "Invoke-D365SysRunnerClass Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365SysRunnerClass).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter ClassName' { $parameter = (Get-Command Invoke-D365SysRunnerClass).Parameters['ClassName'] $parameter.Name | Should -Be 'ClassName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Company' { $parameter = (Get-Command Invoke-D365SysRunnerClass).Parameters['Company'] $parameter.Name | Should -Be 'Company' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 2 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Url' { $parameter = (Get-Command Invoke-D365SysRunnerClass).Parameters['Url'] $parameter.Name | Should -Be 'Url' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 3 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -ClassName Default -ClassName -Company -Url #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365TableBrowser.Tests.ps1 ================================================ Describe "Invoke-D365TableBrowser Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365TableBrowser).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter TableName' { $parameter = (Get-Command Invoke-D365TableBrowser).Parameters['TableName'] $parameter.Name | Should -Be 'TableName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Company' { $parameter = (Get-Command Invoke-D365TableBrowser).Parameters['Company'] $parameter.Name | Should -Be 'Company' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 2 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Url' { $parameter = (Get-Command Invoke-D365TableBrowser).Parameters['Url'] $parameter.Name | Should -Be 'Url' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 3 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -TableName Default -TableName -Company -Url #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365VisualStudioCompilerResultAnalyzer.Tests.ps1 ================================================ Describe "Invoke-D365VisualStudioCompilerResultAnalyzer Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365VisualStudioCompilerResultAnalyzer).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Module' { $parameter = (Get-Command Invoke-D365VisualStudioCompilerResultAnalyzer).Parameters['Module'] $parameter.Name | Should -Be 'Module' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Invoke-D365VisualStudioCompilerResultAnalyzer).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SkipWarnings' { $parameter = (Get-Command Invoke-D365VisualStudioCompilerResultAnalyzer).Parameters['SkipWarnings'] $parameter.Name | Should -Be 'SkipWarnings' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SkipTasks' { $parameter = (Get-Command Invoke-D365VisualStudioCompilerResultAnalyzer).Parameters['SkipTasks'] $parameter.Name | Should -Be 'SkipTasks' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Invoke-D365VisualStudioCompilerResultAnalyzer).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Module -OutputPath -SkipWarnings -SkipTasks -PackageDirectory #> } } ================================================ FILE: d365fo.tools/tests/functions/Invoke-D365WinRmCertificateRotation.Tests.ps1 ================================================ Describe "Invoke-D365WinRmCertificateRotation Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Invoke-D365WinRmCertificateRotation).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter MachineName' { $parameter = (Get-Command Invoke-D365WinRmCertificateRotation).Parameters['MachineName'] $parameter.Name | Should -Be 'MachineName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -MachineName #> } } ================================================ FILE: d365fo.tools/tests/functions/New-D365Bacpac.Tests.ps1 ================================================ Describe "New-D365Bacpac Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command New-D365Bacpac).ParameterSets.Name | Should -Be 'ExportTier2', 'ExportTier1' } It 'Should have the expected parameter ExportModeTier1' { $parameter = (Get-Command New-D365Bacpac).Parameters['ExportModeTier1'] $parameter.Name | Should -Be 'ExportModeTier1' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ExportTier1' $parameter.ParameterSets.Keys | Should -Contain 'ExportTier1' $parameter.ParameterSets['ExportTier1'].IsMandatory | Should -Be $True $parameter.ParameterSets['ExportTier1'].Position | Should -Be 0 $parameter.ParameterSets['ExportTier1'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ExportTier1'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ExportTier1'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ExportModeTier2' { $parameter = (Get-Command New-D365Bacpac).Parameters['ExportModeTier2'] $parameter.Name | Should -Be 'ExportModeTier2' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ExportTier2' $parameter.ParameterSets.Keys | Should -Contain 'ExportTier2' $parameter.ParameterSets['ExportTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ExportTier2'].Position | Should -Be 0 $parameter.ParameterSets['ExportTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ExportTier2'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ExportTier2'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command New-D365Bacpac).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command New-D365Bacpac).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command New-D365Bacpac).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ExportTier2', '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain 'ExportTier2' $parameter.ParameterSets['ExportTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ExportTier2'].Position | Should -Be 3 $parameter.ParameterSets['ExportTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ExportTier2'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['ExportTier2'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command New-D365Bacpac).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ExportTier2', '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain 'ExportTier2' $parameter.ParameterSets['ExportTier2'].IsMandatory | Should -Be $True $parameter.ParameterSets['ExportTier2'].Position | Should -Be 4 $parameter.ParameterSets['ExportTier2'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ExportTier2'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['ExportTier2'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BackupDirectory' { $parameter = (Get-Command New-D365Bacpac).Parameters['BackupDirectory'] $parameter.Name | Should -Be 'BackupDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ExportTier1' $parameter.ParameterSets.Keys | Should -Contain 'ExportTier1' $parameter.ParameterSets['ExportTier1'].IsMandatory | Should -Be $False $parameter.ParameterSets['ExportTier1'].Position | Should -Be 5 $parameter.ParameterSets['ExportTier1'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ExportTier1'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ExportTier1'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter NewDatabaseName' { $parameter = (Get-Command New-D365Bacpac).Parameters['NewDatabaseName'] $parameter.Name | Should -Be 'NewDatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BacpacFile' { $parameter = (Get-Command New-D365Bacpac).Parameters['BacpacFile'] $parameter.Name | Should -Be 'BacpacFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter CustomSqlFile' { $parameter = (Get-Command New-D365Bacpac).Parameters['CustomSqlFile'] $parameter.Name | Should -Be 'CustomSqlFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DiagnosticFile' { $parameter = (Get-Command New-D365Bacpac).Parameters['DiagnosticFile'] $parameter.Name | Should -Be 'DiagnosticFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ExportOnly' { $parameter = (Get-Command New-D365Bacpac).Parameters['ExportOnly'] $parameter.Name | Should -Be 'ExportOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MaxParallelism' { $parameter = (Get-Command New-D365Bacpac).Parameters['MaxParallelism'] $parameter.Name | Should -Be 'MaxParallelism' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command New-D365Bacpac).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command New-D365Bacpac).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command New-D365Bacpac).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset ExportTier2" { <# ExportTier2 -ExportModeTier2 -SqlUser -SqlPwd ExportTier2 -ExportModeTier2 -DatabaseServer -DatabaseName -SqlUser -SqlPwd -NewDatabaseName -BacpacFile -CustomSqlFile -DiagnosticFile -ExportOnly -MaxParallelism -ShowOriginalProgress -OutputCommandOnly -EnableException #> } Describe "Testing parameterset ExportTier1" { <# ExportTier1 -ExportModeTier1 ExportTier1 -ExportModeTier1 -DatabaseServer -DatabaseName -SqlUser -SqlPwd -BackupDirectory -NewDatabaseName -BacpacFile -CustomSqlFile -DiagnosticFile -ExportOnly -MaxParallelism -ShowOriginalProgress -OutputCommandOnly -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/New-D365CAReport.Tests.ps1 ================================================ Describe "New-D365CAReport Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command New-D365CAReport).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command New-D365CAReport).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Module' { $parameter = (Get-Command New-D365CAReport).Parameters['Module'] $parameter.Name | Should -Be 'Module' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Model' { $parameter = (Get-Command New-D365CAReport).Parameters['Model'] $parameter.Name | Should -Be 'Model' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SuffixWithModule' { $parameter = (Get-Command New-D365CAReport).Parameters['SuffixWithModule'] $parameter.Name | Should -Be 'SuffixWithModule' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command New-D365CAReport).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command New-D365CAReport).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter XmlLog' { $parameter = (Get-Command New-D365CAReport).Parameters['XmlLog'] $parameter.Name | Should -Be 'XmlLog' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackagesRoot' { $parameter = (Get-Command New-D365CAReport).Parameters['PackagesRoot'] $parameter.Name | Should -Be 'PackagesRoot' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command New-D365CAReport).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command New-D365CAReport).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command New-D365CAReport).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Module -Model __AllParameterSets -OutputPath -Module -Model -SuffixWithModule -BinDir -MetaDataDir -XmlLog -PackagesRoot -LogPath -ShowOriginalProgress -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/New-D365EntraIntegration.Tests.ps1 ================================================ Describe "New-D365EntraIntegration Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command New-D365EntraIntegration).ParameterSets.Name | Should -Be 'NewCertificate', 'ExistingCertificate' } It 'Should have the expected parameter ClientId' { $parameter = (Get-Command New-D365EntraIntegration).Parameters['ClientId'] $parameter.Name | Should -Be 'ClientId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ExistingCertificateFile' { $parameter = (Get-Command New-D365EntraIntegration).Parameters['ExistingCertificateFile'] $parameter.Name | Should -Be 'ExistingCertificateFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ExistingCertificate' $parameter.ParameterSets.Keys | Should -Contain 'ExistingCertificate' $parameter.ParameterSets['ExistingCertificate'].IsMandatory | Should -Be $True $parameter.ParameterSets['ExistingCertificate'].Position | Should -Be -2147483648 $parameter.ParameterSets['ExistingCertificate'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ExistingCertificate'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ExistingCertificate'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ExistingCertificatePrivateKeyFile' { $parameter = (Get-Command New-D365EntraIntegration).Parameters['ExistingCertificatePrivateKeyFile'] $parameter.Name | Should -Be 'ExistingCertificatePrivateKeyFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'ExistingCertificate' $parameter.ParameterSets.Keys | Should -Contain 'ExistingCertificate' $parameter.ParameterSets['ExistingCertificate'].IsMandatory | Should -Be $False $parameter.ParameterSets['ExistingCertificate'].Position | Should -Be -2147483648 $parameter.ParameterSets['ExistingCertificate'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['ExistingCertificate'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['ExistingCertificate'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter CertificateName' { $parameter = (Get-Command New-D365EntraIntegration).Parameters['CertificateName'] $parameter.Name | Should -Be 'CertificateName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'NewCertificate' $parameter.ParameterSets.Keys | Should -Contain 'NewCertificate' $parameter.ParameterSets['NewCertificate'].IsMandatory | Should -Be $False $parameter.ParameterSets['NewCertificate'].Position | Should -Be -2147483648 $parameter.ParameterSets['NewCertificate'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['NewCertificate'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['NewCertificate'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter CertificateExpirationYears' { $parameter = (Get-Command New-D365EntraIntegration).Parameters['CertificateExpirationYears'] $parameter.Name | Should -Be 'CertificateExpirationYears' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'NewCertificate' $parameter.ParameterSets.Keys | Should -Contain 'NewCertificate' $parameter.ParameterSets['NewCertificate'].IsMandatory | Should -Be $False $parameter.ParameterSets['NewCertificate'].Position | Should -Be -2147483648 $parameter.ParameterSets['NewCertificate'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['NewCertificate'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['NewCertificate'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter NewCertificateFile' { $parameter = (Get-Command New-D365EntraIntegration).Parameters['NewCertificateFile'] $parameter.Name | Should -Be 'NewCertificateFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'NewCertificate' $parameter.ParameterSets.Keys | Should -Contain 'NewCertificate' $parameter.ParameterSets['NewCertificate'].IsMandatory | Should -Be $False $parameter.ParameterSets['NewCertificate'].Position | Should -Be -2147483648 $parameter.ParameterSets['NewCertificate'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['NewCertificate'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['NewCertificate'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter NewCertificatePrivateKeyFile' { $parameter = (Get-Command New-D365EntraIntegration).Parameters['NewCertificatePrivateKeyFile'] $parameter.Name | Should -Be 'NewCertificatePrivateKeyFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'NewCertificate' $parameter.ParameterSets.Keys | Should -Contain 'NewCertificate' $parameter.ParameterSets['NewCertificate'].IsMandatory | Should -Be $False $parameter.ParameterSets['NewCertificate'].Position | Should -Be -2147483648 $parameter.ParameterSets['NewCertificate'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['NewCertificate'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['NewCertificate'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter CertificatePassword' { $parameter = (Get-Command New-D365EntraIntegration).Parameters['CertificatePassword'] $parameter.Name | Should -Be 'CertificatePassword' $parameter.ParameterType.ToString() | Should -Be System.Security.SecureString $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command New-D365EntraIntegration).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset NewCertificate" { <# NewCertificate -ClientId NewCertificate -ClientId -CertificateName -CertificateExpirationYears -NewCertificateFile -NewCertificatePrivateKeyFile -CertificatePassword -Force #> } Describe "Testing parameterset ExistingCertificate" { <# ExistingCertificate -ClientId -ExistingCertificateFile ExistingCertificate -ClientId -ExistingCertificateFile -ExistingCertificatePrivateKeyFile -CertificatePassword -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/New-D365ISVLicense.Tests.ps1 ================================================ Describe "New-D365ISVLicense Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command New-D365ISVLicense).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter LicenseFile' { $parameter = (Get-Command New-D365ISVLicense).Parameters['LicenseFile'] $parameter.Name | Should -Be 'LicenseFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Path' { $parameter = (Get-Command New-D365ISVLicense).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command New-D365ISVLicense).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -LicenseFile __AllParameterSets -LicenseFile -Path -OutputPath #> } } ================================================ FILE: d365fo.tools/tests/functions/New-D365ModuleToRemove.Tests.ps1 ================================================ Describe "New-D365ModuleToRemove Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command New-D365ModuleToRemove).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter Path' { $parameter = (Get-Command New-D365ModuleToRemove).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Modules' { $parameter = (Get-Command New-D365ModuleToRemove).Parameters['Modules'] $parameter.Name | Should -Be 'Modules' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be 2 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -Path -Modules Default -Path -Modules #> } } ================================================ FILE: d365fo.tools/tests/functions/New-D365TopologyFile.Tests.ps1 ================================================ Describe "New-D365TopologyFile Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command New-D365TopologyFile).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter Path' { $parameter = (Get-Command New-D365TopologyFile).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Services' { $parameter = (Get-Command New-D365TopologyFile).Parameters['Services'] $parameter.Name | Should -Be 'Services' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be 2 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter NewPath' { $parameter = (Get-Command New-D365TopologyFile).Parameters['NewPath'] $parameter.Name | Should -Be 'NewPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be 3 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -Path -Services -NewPath Default -Path -Services -NewPath #> } } ================================================ FILE: d365fo.tools/tests/functions/Publish-D365SsrsReport.Tests.ps1 ================================================ Describe "Publish-D365SsrsReport Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Publish-D365SsrsReport).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Module' { $parameter = (Get-Command Publish-D365SsrsReport).Parameters['Module'] $parameter.Name | Should -Be 'Module' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ReportName' { $parameter = (Get-Command Publish-D365SsrsReport).Parameters['ReportName'] $parameter.Name | Should -Be 'ReportName' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogFile' { $parameter = (Get-Command Publish-D365SsrsReport).Parameters['LogFile'] $parameter.Name | Should -Be 'LogFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Publish-D365SsrsReport).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ToolsBasePath' { $parameter = (Get-Command Publish-D365SsrsReport).Parameters['ToolsBasePath'] $parameter.Name | Should -Be 'ToolsBasePath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ReportServerIp' { $parameter = (Get-Command Publish-D365SsrsReport).Parameters['ReportServerIp'] $parameter.Name | Should -Be 'ReportServerIp' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Module -ReportName -LogFile -PackageDirectory -ToolsBasePath -ReportServerIp #> } } ================================================ FILE: d365fo.tools/tests/functions/Publish-D365WebResources.Tests.ps1 ================================================ Describe "Publish-D365WebResources Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Publish-D365WebResources).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter PackageDirectory' { $parameter = (Get-Command Publish-D365WebResources).Parameters['PackageDirectory'] $parameter.Name | Should -Be 'PackageDirectory' $parameter.ParameterType.ToString() | Should -Be PSFramework.Parameter.PathDirectoryParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AosServiceWebRootPath' { $parameter = (Get-Command Publish-D365WebResources).Parameters['AosServiceWebRootPath'] $parameter.Name | Should -Be 'AosServiceWebRootPath' $parameter.ParameterType.ToString() | Should -Be PSFramework.Parameter.PathDirectoryParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -PackageDirectory -AosServiceWebRootPath #> } } ================================================ FILE: d365fo.tools/tests/functions/Register-D365AzureStorageConfig.Tests.ps1 ================================================ Describe "Register-D365AzureStorageConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Register-D365AzureStorageConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ConfigStorageLocation' { $parameter = (Get-Command Register-D365AzureStorageConfig).Parameters['ConfigStorageLocation'] $parameter.Name | Should -Be 'ConfigStorageLocation' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -ConfigStorageLocation #> } } ================================================ FILE: d365fo.tools/tests/functions/Remove-D365BroadcastMessageConfig.Tests.ps1 ================================================ Describe "Remove-D365BroadcastMessageConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Remove-D365BroadcastMessageConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Remove-D365BroadcastMessageConfig).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Temporary' { $parameter = (Get-Command Remove-D365BroadcastMessageConfig).Parameters['Temporary'] $parameter.Name | Should -Be 'Temporary' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Name __AllParameterSets -Name -Temporary #> } } ================================================ FILE: d365fo.tools/tests/functions/Remove-D365Database.Tests.ps1 ================================================ Describe "Remove-D365Database Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Remove-D365Database).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Remove-D365Database).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Remove-D365Database).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Remove-D365Database).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Remove-D365Database).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Remove-D365Database).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Remove-D365Database).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -EnableException -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/Remove-D365LcsAssetFile.Tests.ps1 ================================================ Describe "Remove-D365LcsAssetFile Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Remove-D365LcsAssetFile).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Remove-D365LcsAssetFile).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AssetId' { $parameter = (Get-Command Remove-D365LcsAssetFile).Parameters['AssetId'] $parameter.Name | Should -Be 'AssetId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Remove-D365LcsAssetFile).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Remove-D365LcsAssetFile).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RetryTimeout' { $parameter = (Get-Command Remove-D365LcsAssetFile).Parameters['RetryTimeout'] $parameter.Name | Should -Be 'RetryTimeout' $parameter.ParameterType.ToString() | Should -Be System.TimeSpan $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Remove-D365LcsAssetFile).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -AssetId __AllParameterSets -ProjectId -AssetId -BearerToken -LcsApiUri -RetryTimeout -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Remove-D365Model.Tests.ps1 ================================================ Describe "Remove-D365Model Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Remove-D365Model).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Model' { $parameter = (Get-Command Remove-D365Model).Parameters['Model'] $parameter.Name | Should -Be 'Model' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Remove-D365Model).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MetaDataDir' { $parameter = (Get-Command Remove-D365Model).Parameters['MetaDataDir'] $parameter.Name | Should -Be 'MetaDataDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DeleteFolders' { $parameter = (Get-Command Remove-D365Model).Parameters['DeleteFolders'] $parameter.Name | Should -Be 'DeleteFolders' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Remove-D365Model).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Remove-D365Model).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Model __AllParameterSets -Model -BinDir -MetaDataDir -DeleteFolders -ShowOriginalProgress -OutputCommandOnly #> } } ================================================ FILE: d365fo.tools/tests/functions/Remove-D365User.Tests.ps1 ================================================ Describe "Remove-D365User Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Remove-D365User).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Remove-D365User).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Remove-D365User).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Remove-D365User).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Remove-D365User).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Email' { $parameter = (Get-Command Remove-D365User).Parameters['Email'] $parameter.Name | Should -Be 'Email' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Email __AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -Email #> } } ================================================ FILE: d365fo.tools/tests/functions/Rename-D365ComputerName.Tests.ps1 ================================================ Describe "Rename-D365ComputerName Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Rename-D365ComputerName).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter NewName' { $parameter = (Get-Command Rename-D365ComputerName).Parameters['NewName'] $parameter.Name | Should -Be 'NewName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SSRSReportDatabase' { $parameter = (Get-Command Rename-D365ComputerName).Parameters['SSRSReportDatabase'] $parameter.Name | Should -Be 'SSRSReportDatabase' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Rename-D365ComputerName).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Rename-D365ComputerName).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Rename-D365ComputerName).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Rename-D365ComputerName).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LogPath' { $parameter = (Get-Command Rename-D365ComputerName).Parameters['LogPath'] $parameter.Name | Should -Be 'LogPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Rename-D365ComputerName).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputCommandOnly' { $parameter = (Get-Command Rename-D365ComputerName).Parameters['OutputCommandOnly'] $parameter.Name | Should -Be 'OutputCommandOnly' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Rename-D365ComputerName).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -NewName __AllParameterSets -NewName -SSRSReportDatabase -DatabaseServer -DatabaseName -SqlUser -SqlPwd -LogPath -ShowOriginalProgress -OutputCommandOnly -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Rename-D365Instance.Tests.ps1 ================================================ Describe "Rename-D365Instance Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Rename-D365Instance).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter NewName' { $parameter = (Get-Command Rename-D365Instance).Parameters['NewName'] $parameter.Name | Should -Be 'NewName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AosServiceWebRootPath' { $parameter = (Get-Command Rename-D365Instance).Parameters['AosServiceWebRootPath'] $parameter.Name | Should -Be 'AosServiceWebRootPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter IISServerApplicationHostConfigFile' { $parameter = (Get-Command Rename-D365Instance).Parameters['IISServerApplicationHostConfigFile'] $parameter.Name | Should -Be 'IISServerApplicationHostConfigFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter HostsFile' { $parameter = (Get-Command Rename-D365Instance).Parameters['HostsFile'] $parameter.Name | Should -Be 'HostsFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BackupExtension' { $parameter = (Get-Command Rename-D365Instance).Parameters['BackupExtension'] $parameter.Name | Should -Be 'BackupExtension' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MRConfigFile' { $parameter = (Get-Command Rename-D365Instance).Parameters['MRConfigFile'] $parameter.Name | Should -Be 'MRConfigFile' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -NewName __AllParameterSets -NewName -AosServiceWebRootPath -IISServerApplicationHostConfigFile -HostsFile -BackupExtension -MRConfigFile #> } } ================================================ FILE: d365fo.tools/tests/functions/Repair-D365BacpacModelFile.Tests.ps1 ================================================ Describe "Repair-D365BacpacModelFile Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Repair-D365BacpacModelFile).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Repair-D365BacpacModelFile).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Repair-D365BacpacModelFile).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PathRepairSimple' { $parameter = (Get-Command Repair-D365BacpacModelFile).Parameters['PathRepairSimple'] $parameter.Name | Should -Be 'PathRepairSimple' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PathRepairQualifier' { $parameter = (Get-Command Repair-D365BacpacModelFile).Parameters['PathRepairQualifier'] $parameter.Name | Should -Be 'PathRepairQualifier' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter PathRepairReplace' { $parameter = (Get-Command Repair-D365BacpacModelFile).Parameters['PathRepairReplace'] $parameter.Name | Should -Be 'PathRepairReplace' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter KeepFiles' { $parameter = (Get-Command Repair-D365BacpacModelFile).Parameters['KeepFiles'] $parameter.Name | Should -Be 'KeepFiles' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Repair-D365BacpacModelFile).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path __AllParameterSets -Path -OutputPath -PathRepairSimple -PathRepairQualifier -PathRepairReplace -KeepFiles -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/Restart-D365Environment.Tests.ps1 ================================================ Describe "Restart-D365Environment Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Restart-D365Environment).ParameterSets.Name | Should -Be 'Default', 'Specific' } It 'Should have the expected parameter ComputerName' { $parameter = (Get-Command Restart-D365Environment).Parameters['ComputerName'] $parameter.Name | Should -Be 'ComputerName' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific', 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 1 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter All' { $parameter = (Get-Command Restart-D365Environment).Parameters['All'] $parameter.Name | Should -Be 'All' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 2 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Aos' { $parameter = (Get-Command Restart-D365Environment).Parameters['Aos'] $parameter.Name | Should -Be 'Aos' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 2 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Batch' { $parameter = (Get-Command Restart-D365Environment).Parameters['Batch'] $parameter.Name | Should -Be 'Batch' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 3 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FinancialReporter' { $parameter = (Get-Command Restart-D365Environment).Parameters['FinancialReporter'] $parameter.Name | Should -Be 'FinancialReporter' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 4 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DMF' { $parameter = (Get-Command Restart-D365Environment).Parameters['DMF'] $parameter.Name | Should -Be 'DMF' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 5 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Kill' { $parameter = (Get-Command Restart-D365Environment).Parameters['Kill'] $parameter.Name | Should -Be 'Kill' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Restart-D365Environment).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -ComputerName -All -Kill -ShowOriginalProgress #> } Describe "Testing parameterset Specific" { <# Specific - Specific -ComputerName -Aos -Batch -FinancialReporter -DMF -Kill -ShowOriginalProgress #> } } ================================================ FILE: d365fo.tools/tests/functions/Restore-D365DevConfig.Tests.ps1 ================================================ Describe "Restore-D365DevConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Restore-D365DevConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Restore-D365DevConfig).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Restore-D365DevConfig).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Path -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/Restore-D365WebConfig.Tests.ps1 ================================================ Describe "Restore-D365WebConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Restore-D365WebConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Restore-D365WebConfig).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Restore-D365WebConfig).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Path -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/Send-D365BroadcastMessage.Tests.ps1 ================================================ Describe "Send-D365BroadcastMessage Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Send-D365BroadcastMessage).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Tenant' { $parameter = (Get-Command Send-D365BroadcastMessage).Parameters['Tenant'] $parameter.Name | Should -Be 'Tenant' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter URL' { $parameter = (Get-Command Send-D365BroadcastMessage).Parameters['URL'] $parameter.Name | Should -Be 'URL' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ClientId' { $parameter = (Get-Command Send-D365BroadcastMessage).Parameters['ClientId'] $parameter.Name | Should -Be 'ClientId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ClientSecret' { $parameter = (Get-Command Send-D365BroadcastMessage).Parameters['ClientSecret'] $parameter.Name | Should -Be 'ClientSecret' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter TimeZone' { $parameter = (Get-Command Send-D365BroadcastMessage).Parameters['TimeZone'] $parameter.Name | Should -Be 'TimeZone' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter StartTime' { $parameter = (Get-Command Send-D365BroadcastMessage).Parameters['StartTime'] $parameter.Name | Should -Be 'StartTime' $parameter.ParameterType.ToString() | Should -Be System.DateTime $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EndingInMinutes' { $parameter = (Get-Command Send-D365BroadcastMessage).Parameters['EndingInMinutes'] $parameter.Name | Should -Be 'EndingInMinutes' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OnPremise' { $parameter = (Get-Command Send-D365BroadcastMessage).Parameters['OnPremise'] $parameter.Name | Should -Be 'OnPremise' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Tenant -URL -ClientId -ClientSecret -TimeZone -StartTime -EndingInMinutes -OnPremise #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365ActiveAzureStorageConfig.Tests.ps1 ================================================ Describe "Set-D365ActiveAzureStorageConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365ActiveAzureStorageConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Set-D365ActiveAzureStorageConfig).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ConfigStorageLocation' { $parameter = (Get-Command Set-D365ActiveAzureStorageConfig).Parameters['ConfigStorageLocation'] $parameter.Name | Should -Be 'ConfigStorageLocation' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Temporary' { $parameter = (Get-Command Set-D365ActiveAzureStorageConfig).Parameters['Temporary'] $parameter.Name | Should -Be 'Temporary' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -Name -ConfigStorageLocation -Temporary #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365ActiveBroadcastMessageConfig.Tests.ps1 ================================================ Describe "Set-D365ActiveBroadcastMessageConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365ActiveBroadcastMessageConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Set-D365ActiveBroadcastMessageConfig).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Temporary' { $parameter = (Get-Command Set-D365ActiveBroadcastMessageConfig).Parameters['Temporary'] $parameter.Name | Should -Be 'Temporary' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Name __AllParameterSets -Name -Temporary #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365Admin.Tests.ps1 ================================================ Describe "Set-D365Admin Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365Admin).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter AdminSignInName' { $parameter = (Get-Command Set-D365Admin).Parameters['AdminSignInName'] $parameter.Name | Should -Be 'AdminSignInName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Set-D365Admin).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Set-D365Admin).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Set-D365Admin).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Set-D365Admin).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Set-D365Admin).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -AdminSignInName __AllParameterSets -AdminSignInName -DatabaseServer -DatabaseName -SqlUser -SqlPwd -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365AzCopyPath.Tests.ps1 ================================================ Describe "Set-D365AzCopyPath Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365AzCopyPath).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Set-D365AzCopyPath).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path __AllParameterSets -Path #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365ClickOnceTrustPrompt.Tests.ps1 ================================================ Describe "Set-D365ClickOnceTrustPrompt Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365ClickOnceTrustPrompt).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365DefaultModelForNewProjects.Tests.ps1 ================================================ Describe "Set-D365DefaultModelForNewProjects Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365DefaultModelForNewProjects).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Module' { $parameter = (Get-Command Set-D365DefaultModelForNewProjects).Parameters['Module'] $parameter.Name | Should -Be 'Module' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Module __AllParameterSets -Module #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365FavoriteBookmark.Tests.ps1 ================================================ Describe "Set-D365FavoriteBookmark Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365FavoriteBookmark).ParameterSets.Name | Should -Be 'D365FO', 'AzureDevOps' } It 'Should have the expected parameter URL' { $parameter = (Get-Command Set-D365FavoriteBookmark).Parameters['URL'] $parameter.Name | Should -Be 'URL' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter D365FO' { $parameter = (Get-Command Set-D365FavoriteBookmark).Parameters['D365FO'] $parameter.Name | Should -Be 'D365FO' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'D365FO' $parameter.ParameterSets.Keys | Should -Contain 'D365FO' $parameter.ParameterSets['D365FO'].IsMandatory | Should -Be $False $parameter.ParameterSets['D365FO'].Position | Should -Be -2147483648 $parameter.ParameterSets['D365FO'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['D365FO'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['D365FO'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AzureDevOps' { $parameter = (Get-Command Set-D365FavoriteBookmark).Parameters['AzureDevOps'] $parameter.Name | Should -Be 'AzureDevOps' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'AzureDevOps' $parameter.ParameterSets.Keys | Should -Contain 'AzureDevOps' $parameter.ParameterSets['AzureDevOps'].IsMandatory | Should -Be $False $parameter.ParameterSets['AzureDevOps'].Position | Should -Be -2147483648 $parameter.ParameterSets['AzureDevOps'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['AzureDevOps'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['AzureDevOps'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset D365FO" { <# D365FO - D365FO -URL -D365FO #> } Describe "Testing parameterset AzureDevOps" { <# AzureDevOps - AzureDevOps -URL -AzureDevOps #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365FlightServiceCatalogId.Tests.ps1 ================================================ Describe "Set-D365FlightServiceCatalogId Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365FlightServiceCatalogId).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter FlightServiceCatalogId' { $parameter = (Get-Command Set-D365FlightServiceCatalogId).Parameters['FlightServiceCatalogId'] $parameter.Name | Should -Be 'FlightServiceCatalogId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AosServiceWebRootPath' { $parameter = (Get-Command Set-D365FlightServiceCatalogId).Parameters['AosServiceWebRootPath'] $parameter.Name | Should -Be 'AosServiceWebRootPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -FlightServiceCatalogId -AosServiceWebRootPath #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365LcsApiConfig.Tests.ps1 ================================================ Describe "Set-D365LcsApiConfig Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365LcsApiConfig).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ProjectId' { $parameter = (Get-Command Set-D365LcsApiConfig).Parameters['ProjectId'] $parameter.Name | Should -Be 'ProjectId' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ClientId' { $parameter = (Get-Command Set-D365LcsApiConfig).Parameters['ClientId'] $parameter.Name | Should -Be 'ClientId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BearerToken' { $parameter = (Get-Command Set-D365LcsApiConfig).Parameters['BearerToken'] $parameter.Name | Should -Be 'BearerToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ActiveTokenExpiresOn' { $parameter = (Get-Command Set-D365LcsApiConfig).Parameters['ActiveTokenExpiresOn'] $parameter.Name | Should -Be 'ActiveTokenExpiresOn' $parameter.ParameterType.ToString() | Should -Be System.Int64 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RefreshToken' { $parameter = (Get-Command Set-D365LcsApiConfig).Parameters['RefreshToken'] $parameter.Name | Should -Be 'RefreshToken' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter LcsApiUri' { $parameter = (Get-Command Set-D365LcsApiConfig).Parameters['LcsApiUri'] $parameter.Name | Should -Be 'LcsApiUri' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Temporary' { $parameter = (Get-Command Set-D365LcsApiConfig).Parameters['Temporary'] $parameter.Name | Should -Be 'Temporary' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -ProjectId -ClientId -BearerToken -ActiveTokenExpiresOn -RefreshToken -LcsApiUri -Temporary #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365NugetPath.Tests.ps1 ================================================ Describe "Set-D365NugetPath Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365NugetPath).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Set-D365NugetPath).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path __AllParameterSets -Path #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365OfflineAuthenticationAdminEmail.Tests.ps1 ================================================ Describe "Set-D365OfflineAuthenticationAdminEmail Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365OfflineAuthenticationAdminEmail).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter Email' { $parameter = (Get-Command Set-D365OfflineAuthenticationAdminEmail).Parameters['Email'] $parameter.Name | Should -Be 'Email' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -Email Default -Email #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365RsatConfiguration.Tests.ps1 ================================================ Describe "Set-D365RsatConfiguration Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365RsatConfiguration).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter LogGenerationEnabled' { $parameter = (Get-Command Set-D365RsatConfiguration).Parameters['LogGenerationEnabled'] $parameter.Name | Should -Be 'LogGenerationEnabled' $parameter.ParameterType.ToString() | Should -Be System.Boolean $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter VerboseSnapshotsEnabled' { $parameter = (Get-Command Set-D365RsatConfiguration).Parameters['VerboseSnapshotsEnabled'] $parameter.Name | Should -Be 'VerboseSnapshotsEnabled' $parameter.ParameterType.ToString() | Should -Be System.Boolean $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter AddOperatorFieldsToExcelValidationEnabled' { $parameter = (Get-Command Set-D365RsatConfiguration).Parameters['AddOperatorFieldsToExcelValidationEnabled'] $parameter.Name | Should -Be 'AddOperatorFieldsToExcelValidationEnabled' $parameter.ParameterType.ToString() | Should -Be System.Boolean $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter RSATConfigFilename' { $parameter = (Get-Command Set-D365RsatConfiguration).Parameters['RSATConfigFilename'] $parameter.Name | Should -Be 'RSATConfigFilename' $parameter.ParameterType.ToString() | Should -Be System.Object $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -LogGenerationEnabled -VerboseSnapshotsEnabled -AddOperatorFieldsToExcelValidationEnabled -RSATConfigFilename #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365RsatTier2Crypto.Tests.ps1 ================================================ Describe "Set-D365RsatTier2Crypto Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365RsatTier2Crypto).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365SDPCleanUp.Tests.ps1 ================================================ Describe "Set-D365SDPCleanUp Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365SDPCleanUp).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter NumberOfDays' { $parameter = (Get-Command Set-D365SDPCleanUp).Parameters['NumberOfDays'] $parameter.Name | Should -Be 'NumberOfDays' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -NumberOfDays #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365SqlPackagePath.Tests.ps1 ================================================ Describe "Set-D365SqlPackagePath Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365SqlPackagePath).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Set-D365SqlPackagePath).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Path __AllParameterSets -Path #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365StartPage.Tests.ps1 ================================================ Describe "Set-D365StartPage Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365StartPage).ParameterSets.Name | Should -Be 'Default', 'Url' } It 'Should have the expected parameter Name' { $parameter = (Get-Command Set-D365StartPage).Parameters['Name'] $parameter.Name | Should -Be 'Name' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $True $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Url' { $parameter = (Get-Command Set-D365StartPage).Parameters['Url'] $parameter.Name | Should -Be 'Url' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Url' $parameter.ParameterSets.Keys | Should -Contain 'Url' $parameter.ParameterSets['Url'].IsMandatory | Should -Be $True $parameter.ParameterSets['Url'].Position | Should -Be 1 $parameter.ParameterSets['Url'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Url'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['Url'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default -Name Default -Name #> } Describe "Testing parameterset Url" { <# Url -Url Url -Url #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365SysAdmin.Tests.ps1 ================================================ Describe "Set-D365SysAdmin Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365SysAdmin).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter User' { $parameter = (Get-Command Set-D365SysAdmin).Parameters['User'] $parameter.Name | Should -Be 'User' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Set-D365SysAdmin).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Set-D365SysAdmin).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Set-D365SysAdmin).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Set-D365SysAdmin).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -User -DatabaseServer -DatabaseName -SqlUser -SqlPwd #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365TraceParserFileSize.Tests.ps1 ================================================ Describe "Set-D365TraceParserFileSize Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365TraceParserFileSize).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter FileSizeInMB' { $parameter = (Get-Command Set-D365TraceParserFileSize).Parameters['FileSizeInMB'] $parameter.Name | Should -Be 'FileSizeInMB' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Path' { $parameter = (Get-Command Set-D365TraceParserFileSize).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -FileSizeInMB __AllParameterSets -FileSizeInMB -Path #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365WebConfigDatabase.Tests.ps1 ================================================ Describe "Set-D365WebConfigDatabase Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365WebConfigDatabase).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Set-D365WebConfigDatabase).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Set-D365WebConfigDatabase).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Set-D365WebConfigDatabase).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Set-D365WebConfigDatabase).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Path' { $parameter = (Get-Command Set-D365WebConfigDatabase).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.Object $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd __AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -Path #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365WebServerType.Tests.ps1 ================================================ Describe "Set-D365WebServerType Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365WebServerType).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter RuntimeHostType' { $parameter = (Get-Command Set-D365WebServerType).Parameters['RuntimeHostType'] $parameter.Name | Should -Be 'RuntimeHostType' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -RuntimeHostType __AllParameterSets -RuntimeHostType #> } } ================================================ FILE: d365fo.tools/tests/functions/Set-D365WorkstationMode.Tests.ps1 ================================================ Describe "Set-D365WorkstationMode Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Set-D365WorkstationMode).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Enabled' { $parameter = (Get-Command Set-D365WorkstationMode).Parameters['Enabled'] $parameter.Name | Should -Be 'Enabled' $parameter.ParameterType.ToString() | Should -Be System.Boolean $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Enabled __AllParameterSets -Enabled #> } } ================================================ FILE: d365fo.tools/tests/functions/Start-D365Environment.Tests.ps1 ================================================ Describe "Start-D365Environment Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Start-D365Environment).ParameterSets.Name | Should -Be 'Default', 'Specific' } It 'Should have the expected parameter ComputerName' { $parameter = (Get-Command Start-D365Environment).Parameters['ComputerName'] $parameter.Name | Should -Be 'ComputerName' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific', 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 1 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter All' { $parameter = (Get-Command Start-D365Environment).Parameters['All'] $parameter.Name | Should -Be 'All' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 2 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Aos' { $parameter = (Get-Command Start-D365Environment).Parameters['Aos'] $parameter.Name | Should -Be 'Aos' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 2 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Batch' { $parameter = (Get-Command Start-D365Environment).Parameters['Batch'] $parameter.Name | Should -Be 'Batch' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 3 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FinancialReporter' { $parameter = (Get-Command Start-D365Environment).Parameters['FinancialReporter'] $parameter.Name | Should -Be 'FinancialReporter' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 4 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DMF' { $parameter = (Get-Command Start-D365Environment).Parameters['DMF'] $parameter.Name | Should -Be 'DMF' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 5 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OnlyStartTypeAutomatic' { $parameter = (Get-Command Start-D365Environment).Parameters['OnlyStartTypeAutomatic'] $parameter.Name | Should -Be 'OnlyStartTypeAutomatic' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Start-D365Environment).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -ComputerName -All -OnlyStartTypeAutomatic -ShowOriginalProgress #> } Describe "Testing parameterset Specific" { <# Specific - Specific -ComputerName -Aos -Batch -FinancialReporter -DMF -OnlyStartTypeAutomatic -ShowOriginalProgress #> } } ================================================ FILE: d365fo.tools/tests/functions/Start-D365EnvironmentV2.Tests.ps1 ================================================ Describe "Start-D365EnvironmentV2 Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Start-D365EnvironmentV2).ParameterSets.Name | Should -Be 'Default', 'Specific' } It 'Should have the expected parameter All' { $parameter = (Get-Command Start-D365EnvironmentV2).Parameters['All'] $parameter.Name | Should -Be 'All' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Aos' { $parameter = (Get-Command Start-D365EnvironmentV2).Parameters['Aos'] $parameter.Name | Should -Be 'Aos' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 1 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Batch' { $parameter = (Get-Command Start-D365EnvironmentV2).Parameters['Batch'] $parameter.Name | Should -Be 'Batch' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 2 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FinancialReporter' { $parameter = (Get-Command Start-D365EnvironmentV2).Parameters['FinancialReporter'] $parameter.Name | Should -Be 'FinancialReporter' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 3 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DMF' { $parameter = (Get-Command Start-D365EnvironmentV2).Parameters['DMF'] $parameter.Name | Should -Be 'DMF' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 4 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OnlyStartTypeAutomatic' { $parameter = (Get-Command Start-D365EnvironmentV2).Parameters['OnlyStartTypeAutomatic'] $parameter.Name | Should -Be 'OnlyStartTypeAutomatic' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Start-D365EnvironmentV2).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -All -OnlyStartTypeAutomatic -ShowOriginalProgress #> } Describe "Testing parameterset Specific" { <# Specific - Specific -Aos -Batch -FinancialReporter -DMF -OnlyStartTypeAutomatic -ShowOriginalProgress #> } } ================================================ FILE: d365fo.tools/tests/functions/Start-D365EventTrace.Tests.ps1 ================================================ Describe "Start-D365EventTrace Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Start-D365EventTrace).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter ProviderName' { $parameter = (Get-Command Start-D365EventTrace).Parameters['ProviderName'] $parameter.Name | Should -Be 'ProviderName' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Start-D365EventTrace).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SessionName' { $parameter = (Get-Command Start-D365EventTrace).Parameters['SessionName'] $parameter.Name | Should -Be 'SessionName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FileName' { $parameter = (Get-Command Start-D365EventTrace).Parameters['FileName'] $parameter.Name | Should -Be 'FileName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputFormat' { $parameter = (Get-Command Start-D365EventTrace).Parameters['OutputFormat'] $parameter.Name | Should -Be 'OutputFormat' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MinBuffer' { $parameter = (Get-Command Start-D365EventTrace).Parameters['MinBuffer'] $parameter.Name | Should -Be 'MinBuffer' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MaxBuffer' { $parameter = (Get-Command Start-D365EventTrace).Parameters['MaxBuffer'] $parameter.Name | Should -Be 'MaxBuffer' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 6 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter BufferSizeKB' { $parameter = (Get-Command Start-D365EventTrace).Parameters['BufferSizeKB'] $parameter.Name | Should -Be 'BufferSizeKB' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 7 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter MaxLogFileSizeMB' { $parameter = (Get-Command Start-D365EventTrace).Parameters['MaxLogFileSizeMB'] $parameter.Name | Should -Be 'MaxLogFileSizeMB' $parameter.ParameterType.ToString() | Should -Be System.Int32 $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 8 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -ProviderName __AllParameterSets -ProviderName -OutputPath -SessionName -FileName -OutputFormat -MinBuffer -MaxBuffer -BufferSizeKB -MaxLogFileSizeMB #> } } ================================================ FILE: d365fo.tools/tests/functions/Stop-D365Environment.Tests.ps1 ================================================ Describe "Stop-D365Environment Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Stop-D365Environment).ParameterSets.Name | Should -Be 'Default', 'Specific' } It 'Should have the expected parameter ComputerName' { $parameter = (Get-Command Stop-D365Environment).Parameters['ComputerName'] $parameter.Name | Should -Be 'ComputerName' $parameter.ParameterType.ToString() | Should -Be System.String[] $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific', 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 1 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 1 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter All' { $parameter = (Get-Command Stop-D365Environment).Parameters['All'] $parameter.Name | Should -Be 'All' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 2 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Aos' { $parameter = (Get-Command Stop-D365Environment).Parameters['Aos'] $parameter.Name | Should -Be 'Aos' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 2 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Batch' { $parameter = (Get-Command Stop-D365Environment).Parameters['Batch'] $parameter.Name | Should -Be 'Batch' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 3 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter FinancialReporter' { $parameter = (Get-Command Stop-D365Environment).Parameters['FinancialReporter'] $parameter.Name | Should -Be 'FinancialReporter' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 4 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DMF' { $parameter = (Get-Command Stop-D365Environment).Parameters['DMF'] $parameter.Name | Should -Be 'DMF' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 5 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Kill' { $parameter = (Get-Command Stop-D365Environment).Parameters['Kill'] $parameter.Name | Should -Be 'Kill' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default', 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 6 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 6 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowOriginalProgress' { $parameter = (Get-Command Stop-D365Environment).Parameters['ShowOriginalProgress'] $parameter.Name | Should -Be 'ShowOriginalProgress' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be 'Default', 'Specific' $parameter.ParameterSets.Keys | Should -Contain 'Default' $parameter.ParameterSets['Default'].IsMandatory | Should -Be $False $parameter.ParameterSets['Default'].Position | Should -Be 7 $parameter.ParameterSets['Default'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Default'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Default'].ValueFromRemainingArguments | Should -Be $False $parameter.ParameterSets.Keys | Should -Contain 'Specific' $parameter.ParameterSets['Specific'].IsMandatory | Should -Be $False $parameter.ParameterSets['Specific'].Position | Should -Be 7 $parameter.ParameterSets['Specific'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['Specific'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -ComputerName -All -Kill -ShowOriginalProgress #> } Describe "Testing parameterset Specific" { <# Specific - Specific -ComputerName -Aos -Batch -FinancialReporter -DMF -Kill -ShowOriginalProgress #> } } ================================================ FILE: d365fo.tools/tests/functions/Stop-D365EventTrace.Tests.ps1 ================================================ Describe "Stop-D365EventTrace Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Stop-D365EventTrace).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter SessionName' { $parameter = (Get-Command Stop-D365EventTrace).Parameters['SessionName'] $parameter.Name | Should -Be 'SessionName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -SessionName #> } } ================================================ FILE: d365fo.tools/tests/functions/Switch-D365ActiveDatabase.Tests.ps1 ================================================ Describe "Switch-D365ActiveDatabase Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Switch-D365ActiveDatabase).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Switch-D365ActiveDatabase).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Switch-D365ActiveDatabase).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Switch-D365ActiveDatabase).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Switch-D365ActiveDatabase).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SourceDatabaseName' { $parameter = (Get-Command Switch-D365ActiveDatabase).Parameters['SourceDatabaseName'] $parameter.Name | Should -Be 'SourceDatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DestinationSuffix' { $parameter = (Get-Command Switch-D365ActiveDatabase).Parameters['DestinationSuffix'] $parameter.Name | Should -Be 'DestinationSuffix' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter EnableException' { $parameter = (Get-Command Switch-D365ActiveDatabase).Parameters['EnableException'] $parameter.Name | Should -Be 'EnableException' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -SourceDatabaseName __AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -SourceDatabaseName -DestinationSuffix -EnableException #> } } ================================================ FILE: d365fo.tools/tests/functions/Test-D365Command.Tests.ps1 ================================================ Describe "Test-D365Command Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Test-D365Command).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter CommandText' { $parameter = (Get-Command Test-D365Command).Parameters['CommandText'] $parameter.Name | Should -Be 'CommandText' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Mode' { $parameter = (Get-Command Test-D365Command).Parameters['Mode'] $parameter.Name | Should -Be 'Mode' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SplatInput' { $parameter = (Get-Command Test-D365Command).Parameters['SplatInput'] $parameter.Name | Should -Be 'SplatInput' $parameter.ParameterType.ToString() | Should -Be System.Collections.Hashtable $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowSplatStyleV1' { $parameter = (Get-Command Test-D365Command).Parameters['ShowSplatStyleV1'] $parameter.Name | Should -Be 'ShowSplatStyleV1' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter ShowSplatStyleV2' { $parameter = (Get-Command Test-D365Command).Parameters['ShowSplatStyleV2'] $parameter.Name | Should -Be 'ShowSplatStyleV2' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter IncludeHelp' { $parameter = (Get-Command Test-D365Command).Parameters['IncludeHelp'] $parameter.Name | Should -Be 'IncludeHelp' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -CommandText -Mode __AllParameterSets -CommandText -Mode -SplatInput -ShowSplatStyleV1 -ShowSplatStyleV2 -IncludeHelp #> } } ================================================ FILE: d365fo.tools/tests/functions/Test-D365DataverseConnection.Tests.ps1 ================================================ Describe "Test-D365DataverseConnection Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Test-D365DataverseConnection).ParameterSets.Name | Should -Be 'Default' } It 'Should have the expected parameter BinDir' { $parameter = (Get-Command Test-D365DataverseConnection).Parameters['BinDir'] $parameter.Name | Should -Be 'BinDir' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset Default" { <# Default - Default -BinDir #> } } ================================================ FILE: d365fo.tools/tests/functions/Test-D365EntraIntegration.Tests.ps1 ================================================ Describe "Test-D365EntraIntegration Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Test-D365EntraIntegration).ParameterSets.Name | Should -Be '__AllParameterSets' } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets - #> } } ================================================ FILE: d365fo.tools/tests/functions/Test-D365FlightServiceCatalogId.Tests.ps1 ================================================ Describe "Test-D365FlightServiceCatalogId Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Test-D365FlightServiceCatalogId).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter AosServiceWebRootPath' { $parameter = (Get-Command Test-D365FlightServiceCatalogId).Parameters['AosServiceWebRootPath'] $parameter.Name | Should -Be 'AosServiceWebRootPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets - __AllParameterSets -AosServiceWebRootPath #> } } ================================================ FILE: d365fo.tools/tests/functions/Test-D365LabelIdIsValid.Tests.ps1 ================================================ Describe "Test-D365LabelIdIsValid Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Test-D365LabelIdIsValid).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter LabelId' { $parameter = (Get-Command Test-D365LabelIdIsValid).Parameters['LabelId'] $parameter.Name | Should -Be 'LabelId' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -LabelId __AllParameterSets -LabelId #> } } ================================================ FILE: d365fo.tools/tests/functions/Update-D365BacpacModelFileSingleTable.Tests.ps1 ================================================ Describe "Update-D365BacpacModelFileSingleTable Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Update-D365BacpacModelFileSingleTable).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter Path' { $parameter = (Get-Command Update-D365BacpacModelFileSingleTable).Parameters['Path'] $parameter.Name | Should -Be 'Path' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Table' { $parameter = (Get-Command Update-D365BacpacModelFileSingleTable).Parameters['Table'] $parameter.Name | Should -Be 'Table' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Schema' { $parameter = (Get-Command Update-D365BacpacModelFileSingleTable).Parameters['Schema'] $parameter.Name | Should -Be 'Schema' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter OutputPath' { $parameter = (Get-Command Update-D365BacpacModelFileSingleTable).Parameters['OutputPath'] $parameter.Name | Should -Be 'OutputPath' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Force' { $parameter = (Get-Command Update-D365BacpacModelFileSingleTable).Parameters['Force'] $parameter.Name | Should -Be 'Force' $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.SwitchParameter $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Table __AllParameterSets -Path -Table -Schema -OutputPath -Force #> } } ================================================ FILE: d365fo.tools/tests/functions/Update-D365User.Tests.ps1 ================================================ Describe "Update-D365User Unit Tests" -Tag "Unit" { BeforeAll { # Place here all things needed to prepare for the tests } AfterAll { # Here is where all the cleanup tasks go } Describe "Ensuring unchanged command signature" { It "should have the expected parameter sets" { (Get-Command Update-D365User).ParameterSets.Name | Should -Be '__AllParameterSets' } It 'Should have the expected parameter DatabaseServer' { $parameter = (Get-Command Update-D365User).Parameters['DatabaseServer'] $parameter.Name | Should -Be 'DatabaseServer' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter DatabaseName' { $parameter = (Get-Command Update-D365User).Parameters['DatabaseName'] $parameter.Name | Should -Be 'DatabaseName' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 1 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlUser' { $parameter = (Get-Command Update-D365User).Parameters['SqlUser'] $parameter.Name | Should -Be 'SqlUser' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 2 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter SqlPwd' { $parameter = (Get-Command Update-D365User).Parameters['SqlPwd'] $parameter.Name | Should -Be 'SqlPwd' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 3 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Email' { $parameter = (Get-Command Update-D365User).Parameters['Email'] $parameter.Name | Should -Be 'Email' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 4 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $True $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } It 'Should have the expected parameter Company' { $parameter = (Get-Command Update-D365User).Parameters['Company'] $parameter.Name | Should -Be 'Company' $parameter.ParameterType.ToString() | Should -Be System.String $parameter.IsDynamic | Should -Be $False $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 5 $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False } } Describe "Testing parameterset __AllParameterSets" { <# __AllParameterSets -Email __AllParameterSets -DatabaseServer -DatabaseName -SqlUser -SqlPwd -Email -Company #> } } ================================================ FILE: d365fo.tools/tests/general/FileIntegrity.Exceptions.ps1 ================================================ # List of forbidden commands $global:BannedCommands = @( 'Write-Host', 'Write-Verbose', 'Write-Warning', 'Write-Error', 'Write-Output', 'Write-Information', 'Write-Debug' ) <# Contains list of exceptions for banned cmdlets. Insert the file names of files that may contain them. Example: "Write-Host" = @('Write-PSFHostColor.ps1','Write-PSFMessage.ps1') #> $global:MayContainCommand = @{ "Write-Host" = @() "Write-Verbose" = @('invoke-d365dbsync.ps1','invoke-d365dbsyncpartial.ps1') "Write-Warning" = @() "Write-Error" = @() "Write-Output" = @('convertto-hashtable.ps1') "Write-Information" = @() "Write-Debug" = @() } $global:MayContainAlias = @( 'Initialize-D365RsatCertificate' , 'Add-D365RsatWifConfigAuthorityThumbprint' ) ================================================ FILE: d365fo.tools/tests/general/FileIntegrity.Tests.ps1 ================================================ $moduleRoot = (Resolve-Path "$PSScriptRoot\..\..").Path . "$PSScriptRoot\FileIntegrity.Exceptions.ps1" function Get-FileEncoding { <# .SYNOPSIS Tests a file for encoding. .DESCRIPTION Tests a file for encoding. .PARAMETER Path The file to test #> [CmdletBinding()] Param ( [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)] [Alias('FullName')] [string] $Path ) [byte[]]$byte = get-content -Encoding byte -ReadCount 4 -TotalCount 4 -Path $Path if ($byte[0] -eq 0xef -and $byte[1] -eq 0xbb -and $byte[2] -eq 0xbf) { 'UTF8' } elseif ($byte[0] -eq 0xfe -and $byte[1] -eq 0xff) { 'Unicode' } elseif ($byte[0] -eq 0 -and $byte[1] -eq 0 -and $byte[2] -eq 0xfe -and $byte[3] -eq 0xff) { 'UTF32' } elseif ($byte[0] -eq 0x2b -and $byte[1] -eq 0x2f -and $byte[2] -eq 0x76) { 'UTF7' } else { 'Unknown' } } Describe "Verifying integrity of module files" { Context "Validating PS1 Script files" { $allFiles = Get-ChildItem -Path $moduleRoot -Recurse -Filter "*.ps1" | Where-Object FullName -NotLike "$moduleRoot\tests\*" foreach ($file in $allFiles) { $name = $file.FullName.Replace("$moduleRoot\", '') It "[$name] Should have UTF8 encoding" { Get-FileEncoding -Path $file.FullName | Should -Be 'UTF8' } It "[$name] Should have no trailing space" { ($file | Select-String "\s$" | Where-Object { $_.Line.Trim().Length -gt 0}).LineNumber | Should -BeNullOrEmpty } $tokens = $null $parseErrors = $null $ast = [System.Management.Automation.Language.Parser]::ParseFile($file.FullName, [ref]$tokens, [ref]$parseErrors) It "[$name] Should have no syntax errors" { $parseErrors | Should Be $Null } foreach ($command in $global:BannedCommands) { if ($global:MayContainCommand["$command"] -notcontains $file.Name) { It "[$name] Should not use $command" { $tokens | Where-Object Text -EQ $command | Should -BeNullOrEmpty } } } It "[$name] Should not contain aliases" { if ($global:MayContainAlias -notcontains $file.Name) { $tokens | Where-Object TokenFlags -eq CommandName | Where-Object { Test-Path "alias:\$($_.Text)" } | Measure-Object | Select-Object -ExpandProperty Count | Should -Be 0 } } } } Context "Validating help.txt help files" { $allFiles = Get-ChildItem -Path $moduleRoot -Recurse -Filter "*.help.txt" | Where-Object FullName -NotLike "$moduleRoot\tests\*" foreach ($file in $allFiles) { $name = $file.FullName.Replace("$moduleRoot\", '') It "[$name] Should have UTF8 encoding" { Get-FileEncoding -Path $file.FullName | Should -Be 'UTF8' } It "[$name] Should have no trailing space" { ($file | Select-String "\s$" | Where-Object { $_.Line.Trim().Length -gt 0 } | Measure-Object).Count | Should -Be 0 } } } } ================================================ FILE: d365fo.tools/tests/general/Help.Example.Parameters.Tests.ps1 ================================================ $excludeCommands = @( 'Invoke-D365SCDPBundleInstall' , 'Test-D365Command' , 'Test-PathExists' ) $excludeParameters = @( 'EnableException' , 'TrustedConnection' , 'Force' , 'Temporary' , 'OutputCommandOnly' , 'ShowOriginalProgress' , 'OutputAsHashtable' , 'LogPath' , 'FailOnErrorMessage' ) $commandsRaw = Get-Command -Module d365fo.tools if ($excludeCommands.Count -gt 0) { $commands = $commandsRaw | Select-String -Pattern $excludeCommands -SimpleMatch -NotMatch } else { $commands = $commandsRaw } foreach ( $commandName in $commands) { if ($commandName -notlike "*d365*") { continue } # command to be tested # get all examples from the help $examples = Get-Help $commandName -Examples $parameters = (Get-Help $commandName -Full).parameters # make a describe block that will contain tests for this Describe "Parameters without default vaules from $commandName" { foreach ($parm in $parameters.parameter) { if ($parm.defaultValue -ne "False") { continue } $parmName = $parm.name if ($parmName -in $excludeParameters) { continue } $res = $false foreach ($exampleObject in $examples.Examples.Example) { if ($res) { continue } $example = $exampleObject.Code -replace "`n.*" -replace "PS C:\\>" $res = $example -match "-$parmName( *|\:)" } It "$parmName is present in an example" { $res | Should -BeTrue } } } } ================================================ FILE: d365fo.tools/tests/general/Help.Example.Tests.ps1 ================================================ $excludeCommands = @( "Import-ModuleFile" , "Get-DeepClone" , "Test-TrustedConnection" , "Select-DefaultView" , 'QueryDataSourceRecursion' , 'Get-AxDataEntities' ) enum LcsAssetFileType { Model = 1 ProcessDataPackage = 4 SoftwareDeployablePackage = 10 GERConfiguration = 12 DataPackage = 15 PowerBIReportModel = 19 } $commandsRaw = Get-Command -Module d365fo.tools if ($excludeCommands.Count -gt 0) { $commands = $commandsRaw | Select-String -Pattern $excludeCommands -SimpleMatch -NotMatch } else { $commands = $commandsRaw } foreach ( $commandName in $commands) { # command to be tested # get all examples from the help $examples = Get-Help $commandName -Examples # make a describe block that will contain tests for this Describe "Examples from $commandName" { $examples.Examples.Example | foreach { # examples have different format, # at least the ones I used that MS provided # so you need to either standardize them, # or provide some hints about what to do # such as putting the code first # followed by # #output: the desired output # here I am simply taking the first line and removing 'PS C:\>' # which makes some of the tests fail $example = $_.Code -replace "`n.*" -replace "PS C:\\>" if ( ($example -like "*|*" ) -or (-not ($example -match $commandName)) -or ($example -like "*).*")) { It "Example - $example" -Skip { $true } } elseif ($example -match '(?<=^(([^"|^'']\*(? $global:HelpTestEnumeratedArrays = @( ) <# Some types on parameters just fail their validation no matter what. For those it becomes possible to skip them, by adding them to this hashtable. Add by following this convention: = @() Example: "Get-DbaCmObject" = @("DoNotUse") #> $global:HelpTestSkipParameterType = @{ } ================================================ FILE: d365fo.tools/tests/general/Help.Tests.ps1 ================================================ <# .NOTES The original test this is based upon was written by June Blender. After several rounds of modifications it stands now as it is, but the honor remains hers. Thank you June, for all you have done! .DESCRIPTION This test evaluates the help for all commands in a module. .PARAMETER SkipTest Disables this test. .PARAMETER CommandPath List of paths under which the script files are stored. This test assumes that all functions have their own file that is named after themselves. These paths are used to search for commands that should exist and be tested. Will search recursively and accepts wildcards, make sure only functions are found .PARAMETER ModuleName Name of the module to be tested. The module must already be imported .PARAMETER ExceptionsFile File in which exceptions and adjustments are configured. In it there should be two arrays and a hashtable defined: $global:FunctionHelpTestExceptions $global:HelpTestEnumeratedArrays $global:HelpTestSkipParameterType These can be used to tweak the tests slightly in cases of need. See the example file for explanations on each of these usage and effect. #> [CmdletBinding()] Param ( [switch] $SkipTest, [string[]] $CommandPath = @("$PSScriptRoot\..\..\functions", "$PSScriptRoot\..\..\internal\functions"), [string] $ModuleName = "d365fo.tools", [string] $ExceptionsFile = "$PSScriptRoot\Help.Exceptions.ps1" ) if ($SkipTest) { return } . $ExceptionsFile $includedNames = (Get-ChildItem $CommandPath -Recurse -File | Where-Object Name -like "*.ps1").BaseName $commands = Get-Command -Module (Get-Module $ModuleName) -CommandType Cmdlet, Function, Workflow | Where-Object Name -in $includedNames ## When testing help, remember that help is cached at the beginning of each session. ## To test, restart session. foreach ($command in $commands) { $commandName = $command.Name # Skip all functions that are on the exclusions list if ($global:FunctionHelpTestExceptions -contains $commandName) { continue } # The module-qualified command fails on Microsoft.PowerShell.Archive cmdlets $Help = Get-Help $commandName -ErrorAction SilentlyContinue $testhelperrors = 0 $testhelpall = 0 Describe "Test help for $commandName" { $testhelpall += 1 if ($Help.Synopsis -like '*`[``]*') { # If help is not found, synopsis in auto-generated help is the syntax diagram It "should not be auto-generated" { $Help.Synopsis | Should -Not -BeLike '*`[``]*' } $testhelperrors += 1 } $testhelpall += 1 if ([String]::IsNullOrEmpty($Help.Description.Text)) { # Should be a description for every function It "gets description for $commandName" { $Help.Description | Should -Not -BeNullOrEmpty } $testhelperrors += 1 } $testhelpall += 1 if ([String]::IsNullOrEmpty(($Help.Examples.Example | Select-Object -First 1).Code)) { # Should be at least one example It "gets example code from $commandName" { ($Help.Examples.Example | Select-Object -First 1).Code | Should -Not -BeNullOrEmpty } $testhelperrors += 1 } $testhelpall += 1 if ([String]::IsNullOrEmpty(($Help.Examples.Example.Remarks | Select-Object -First 1).Text)) { # Should be at least one example description It "gets example help from $commandName" { ($Help.Examples.Example.Remarks | Select-Object -First 1).Text | Should -Not -BeNullOrEmpty } $testhelperrors += 1 } if ($testhelperrors -eq 0) { It "Ran silently $testhelpall tests" { $testhelperrors | Should -be 0 } } $testparamsall = 0 $testparamserrors = 0 Context "Test parameter help for $commandName" { $Common = 'Debug', 'ErrorAction', 'ErrorVariable', 'InformationAction', 'InformationVariable', 'OutBuffer', 'OutVariable', 'PipelineVariable', 'Verbose', 'WarningAction', 'WarningVariable' $parameters = $command.ParameterSets.Parameters | Sort-Object -Property Name -Unique | Where-Object Name -notin $common $parameterNames = $parameters.Name $HelpParameterNames = $Help.Parameters.Parameter.Name | Sort-Object -Unique foreach ($parameter in $parameters) { $parameterName = $parameter.Name $parameterHelp = $Help.parameters.parameter | Where-Object Name -EQ $parameterName $testparamsall += 1 if ([String]::IsNullOrEmpty($parameterHelp.Description.Text)) { # Should be a description for every parameter It "gets help for parameter: $parameterName : in $commandName" { $parameterHelp.Description.Text | Should -Not -BeNullOrEmpty } $testparamserrors += 1 } $testparamsall += 1 # $codeMandatory = $parameter.IsMandatory.toString() # if ($parameterHelp.Required -ne $codeMandatory) { # # Required value in Help should match IsMandatory property of parameter # It "help for $parameterName parameter in $commandName has correct Mandatory value" { # $parameterHelp.Required | Should -Be $codeMandatory # } # $testparamserrors += 1 # } if ($HelpTestSkipParameterType[$commandName] -contains $parameterName) { continue } $codeType = $parameter.ParameterType.Name $testparamsall += 1 if ($parameter.ParameterType.IsEnum) { # Enumerations often have issues with the typename not being reliably available $names = $parameter.ParameterType::GetNames($parameter.ParameterType) if ($parameterHelp.parameterValueGroup.parameterValue -ne $names) { # Parameter type in Help should match code It "help for $commandName has correct parameter type for $parameterName" { $parameterHelp.parameterValueGroup.parameterValue | Should -be $names } $testparamserrors += 1 } } elseif ($parameter.ParameterType.FullName -in $HelpTestEnumeratedArrays) { # Enumerations often have issues with the typename not being reliably available $names = [Enum]::GetNames($parameter.ParameterType.DeclaredMembers[0].ReturnType) if ($parameterHelp.parameterValueGroup.parameterValue -ne $names) { # Parameter type in Help should match code It "help for $commandName has correct parameter type for $parameterName" { $parameterHelp.parameterValueGroup.parameterValue | Should -be $names } $testparamserrors += 1 } } else { # To avoid calling Trim method on a null object. $helpType = if ($parameterHelp.parameterValue) { $parameterHelp.parameterValue.Trim() } if ($helpType -ne $codeType) { # Parameter type in Help should match code It "help for $commandName has correct parameter type for $parameterName" { $helpType | Should -be $codeType } $testparamserrors += 1 } } } foreach ($helpParm in $HelpParameterNames) { $testparamsall += 1 if ($helpParm -notin $parameterNames) { # Shouldn't find extra parameters in help. It "finds help parameter in code: $helpParm" { $helpParm -in $parameterNames | Should -Be $true } $testparamserrors += 1 } } if ($testparamserrors -eq 0) { It "Ran silently $testparamsall tests" { $testparamserrors | Should -be 0 } } } } } ================================================ FILE: d365fo.tools/tests/general/Manifest.Tests.ps1 ================================================ Describe "Validating the module manifest" { $moduleRoot = (Resolve-Path "$PSScriptRoot\..\..").Path $manifest = ((Get-Content "$moduleRoot\d365fo.tools.psd1") -join "`n") | Invoke-Expression [version]$moduleVersion = Get-Item "$moduleRoot\d365fo.tools.psm1" | Select-String -Pattern '\$script:ModuleVersion = "(.*?)"' | ForEach-Object { $_.Matches[0].Groups[1].Value } Context "Basic resources validation" { $files = Get-ChildItem "$moduleRoot\functions" -Recurse -File -Filter "*.ps1" It "Exports all functions in the public folder" { $functions = (Compare-Object -ReferenceObject $files.BaseName -DifferenceObject $manifest.FunctionsToExport | Where-Object SideIndicator -Like '<=').InputObject $functions | Should -BeNullOrEmpty } It "Exports no function that isn't also present in the public folder" { $functions = (Compare-Object -ReferenceObject $files.BaseName -DifferenceObject $manifest.FunctionsToExport | Where-Object SideIndicator -Like '=>').InputObject $functions | Should -BeNullOrEmpty } It "Exports none of its internal functions" { $files = Get-ChildItem "$moduleRoot\internal\functions" -Recurse -File -Filter "*.ps1" $files | Where-Object BaseName -In $manifest.FunctionsToExport | Should -BeNullOrEmpty } It "Has the same version as the psm1 file" { ([version]$manifest.ModuleVersion) | Should -Be $moduleVersion } } Context "Individual file validation" { It "The root module file exists" { Test-Path "$moduleRoot\$($manifest.RootModule)" | Should -Be $true } foreach ($format in $manifest.FormatsToProcess) { It "The file $format should exist" { Test-Path "$moduleRoot\$format" | Should -Be $true } } foreach ($type in $manifest.TypesToProcess) { It "The file $type should exist" { Test-Path "$moduleRoot\$type" | Should -Be $true } } foreach ($assembly in $manifest.RequiredAssemblies) { It "The file $assembly should exist" { Test-Path "$moduleRoot\$assembly" | Should -Be $true } } } } ================================================ FILE: d365fo.tools/tests/general/PSScriptAnalyzer.Tests.ps1 ================================================ [CmdletBinding()] Param ( [switch] $SkipTest, [string[]] $CommandPath = @("$PSScriptRoot\..\..\functions", "$PSScriptRoot\..\..\internal\functions") ) if ($SkipTest) { return } $list = New-Object System.Collections.ArrayList Describe 'Invoking PSScriptAnalyzer against commandbase' { $commandFiles = Get-ChildItem -Path $CommandPath -Recurse -Filter "*.ps1" $scriptAnalyzerRules = Get-ScriptAnalyzerRule foreach ($file in $commandFiles) { Context "Analyzing $($file.BaseName)" { $analysis = Invoke-ScriptAnalyzer -Path $file.FullName -ExcludeRule PSAvoidTrailingWhitespace, PSShouldProcess, PSReviewUnusedParameter forEach ($rule in $scriptAnalyzerRules) { It "Should pass $rule" { If ($analysis.RuleName -contains $rule) { $analysis | Where-Object RuleName -EQ $rule -outvariable failures | ForEach-Object { $list.Add($_) } 1 | Should Be 0 } else { 0 | Should Be 0 } } } } } } $list | Out-Default ================================================ FILE: d365fo.tools/tests/pester-PSScriptAnalyzer.ps1 ================================================ param ( $TestPublic = $true, $TestInternal = $true, [ValidateSet('None', 'Default', 'Passed', 'Failed', 'Pending', 'Skipped', 'Inconclusive', 'Describe', 'Context', 'Summary', 'Header', 'Fails', 'All')] $Show = "None", $Include = "*", $Exclude = "" ) Write-PSFMessage -Level Important -Message "Starting Tests" Write-PSFMessage -Level Important -Message "Importing Module" Remove-Module d365fo.tools -ErrorAction Ignore Import-Module "$PSScriptRoot\..\d365fo.tools.psd1" Import-Module "$PSScriptRoot\..\d365fo.tools.psm1" -Force Write-PSFMessage -Level Important -Message "Creating test result folder" $null = New-Item -Path "$PSScriptRoot\..\.." -Name TestResults -ItemType Directory -Force $totalFailed = 0 $totalRun = 0 $testresults = @() #region Run Public PSScriptAnalyzer Tests if ($TestPublic) { Write-PSFMessage -Level Important -Message "Modules imported, proceeding with general tests" $file = Get-Item "$PSScriptRoot\general\PSScriptAnalyzer.Tests.ps1" $pesterParm = @{} $pesterParm.Path = $file.FullName $pesterParm.Parameters = @{CommandPath = "$PSScriptRoot\..\functions" } Write-PSFMessage -Level Significant -Message " Executing $($file.Name)" $TestOuputFile = Join-Path "$PSScriptRoot\..\..\TestResults" "TEST-$($file.BaseName).xml" $results = Invoke-Pester -Script $pesterParm -Show $Show -PassThru -OutputFile $TestOuputFile -OutputFormat NUnitXml foreach ($result in $results) { $totalRun += $result.TotalCount $totalFailed += $result.FailedCount $result.TestResult | Where-Object { -not $_.Passed } | ForEach-Object { $name = $_.Name $testresults += [pscustomobject]@{ Describe = $_.Describe Context = $_.Context Name = "It $name" Result = $_.Result Message = $_.FailureMessage } } } } #endregion Run Public PSScriptAnalyzer Tests #region Run Internal PSScriptAnalyzer Tests if ($TestInternal) { Write-PSFMessage -Level Important -Message "Modules imported, proceeding with general tests" $file = Get-Item "$PSScriptRoot\general\PSScriptAnalyzer.Tests.ps1" $pesterParm = @{} $pesterParm.Path = $file.FullName $pesterParm.Parameters = @{CommandPath = "$PSScriptRoot\..\internal\functions" } Write-PSFMessage -Level Significant -Message " Executing $($file.Name)" $TestOuputFile = Join-Path "$PSScriptRoot\..\..\TestResults" "TEST-$($file.BaseName).xml" $results = Invoke-Pester -Script $pesterParm -Show $Show -PassThru -OutputFile $TestOuputFile -OutputFormat NUnitXml foreach ($result in $results) { $totalRun += $result.TotalCount $totalFailed += $result.FailedCount $result.TestResult | Where-Object { -not $_.Passed } | ForEach-Object { $name = $_.Name $testresults += [pscustomobject]@{ Describe = $_.Describe Context = $_.Context Name = "It $name" Result = $_.Result Message = $_.FailureMessage } } } } #endregion Run Internal PSScriptAnalyzer Tests $testresults | Sort-Object Describe, Context, Name, Result, Message | Format-List if ($totalFailed -eq 0) { Write-PSFMessage -Level Critical -Message "All $totalRun tests executed without a single failure!" } else { Write-PSFMessage -Level Critical -Message "$totalFailed tests out of $totalRun tests failed!" } if ($totalFailed -gt 0) { throw "$totalFailed / $totalRun tests failed!" } ================================================ FILE: d365fo.tools/tests/pester.ps1 ================================================ param ( $TestGeneral = $true, $TestFunctions = $true, [ValidateSet('None', 'Default', 'Passed', 'Failed', 'Pending', 'Skipped', 'Inconclusive', 'Describe', 'Context', 'Summary', 'Header', 'Fails', 'All')] $Show = "None", $Include = "*", $Exclude = "" ) Write-PSFMessage -Level Important -Message "Starting Tests" Write-PSFMessage -Level Important -Message "Importing Module" Remove-Module d365fo.tools -ErrorAction Ignore Import-Module "$PSScriptRoot\..\d365fo.tools.psd1" Import-Module "$PSScriptRoot\..\d365fo.tools.psm1" -Force Write-PSFMessage -Level Important -Message "Creating test result folder" $null = New-Item -Path "$PSScriptRoot\..\.." -Name TestResults -ItemType Directory -Force $totalFailed = 0 $totalRun = 0 $testresults = @() #region Run General Tests if ($TestGeneral) { Write-PSFMessage -Level Important -Message "Modules imported, proceeding with general tests" foreach ($file in (Get-ChildItem "$PSScriptRoot\general" -Filter "*.Tests.ps1")) { if ($file.Name -notlike $Include) { continue } if ($file.Name -like $Exclude) { continue } Write-PSFMessage -Level Significant -Message " Executing $($file.Name)" $TestOuputFile = Join-Path "$PSScriptRoot\..\..\TestResults" "TEST-$($file.BaseName).xml" $results = Invoke-Pester -Script $file.FullName -Show $Show -PassThru -OutputFile $TestOuputFile -OutputFormat NUnitXml foreach ($result in $results) { $totalRun += $result.TotalCount $totalFailed += $result.FailedCount $result.TestResult | Where-Object { -not $_.Passed } | ForEach-Object { $name = $_.Name $testresults += [pscustomobject]@{ Describe = $_.Describe Context = $_.Context Name = "It $name" Result = $_.Result Message = $_.FailureMessage } } } } } #endregion Run General Tests #region Test Commands if ($TestFunctions) { Write-PSFMessage -Level Important -Message "Proceeding with individual tests" foreach ($file in (Get-ChildItem "$PSScriptRoot\functions" -Recurse -File -Filter "*Tests.ps1")) { if ($file.Name -notlike $Include) { continue } if ($file.Name -like $Exclude) { continue } Write-PSFMessage -Level Significant -Message " Executing $($file.Name)" $TestOuputFile = Join-Path "$PSScriptRoot\..\..\TestResults" "TEST-$($file.BaseName).xml" $results = Invoke-Pester -Script $file.FullName -Show $Show -PassThru -OutputFile $TestOuputFile -OutputFormat NUnitXml foreach ($result in $results) { $totalRun += $result.TotalCount $totalFailed += $result.FailedCount $result.TestResult | Where-Object { -not $_.Passed } | ForEach-Object { $name = $_.Name $testresults += [pscustomobject]@{ Describe = $_.Describe Context = $_.Context Name = "It $name" Result = $_.Result Message = $_.FailureMessage } } } } } #endregion Test Commands $testresults | Sort-Object Describe, Context, Name, Result, Message | Format-List if ($totalFailed -eq 0) { Write-PSFMessage -Level Critical -Message "All $totalRun tests executed without a single failure!" } else { Write-PSFMessage -Level Critical -Message "$totalFailed tests out of $totalRun tests failed!" } if ($totalFailed -gt 0) { throw "$totalFailed / $totalRun tests failed!" } ================================================ FILE: d365fo.tools/tests/readme.md ================================================ # Description This is the folder, where all the tests go. Those are subdivided in two categories: - General - Function ## General Tests General tests are function generic and test for general policies. These test scan answer questions such as: - Is my module following my style guides? - Does any of my scripts have a syntax error? - Do my scripts use commands I do not want them to use? - Do my commands follow best practices? - Do my commands have proper help? Basically, these allow a general module health check. These tests are already provided as part of the template. ## Function Tests A healthy module should provide unit and integration tests for the commands & components it ships. Only then can be guaranteed, that they will actually perform as promised. However, as each such test must be specific to the function it tests, there cannot be much in the way of templates. ================================================ FILE: d365fo.tools/xml/d365fo.tools.Format.ps1xml ================================================  Foo.Bar Foo.Bar Foo Bar D365FO.TOOLS.Label D365FO.TOOLS.Label 20 80 8 Name Value Language D365FO.TOOLS.ModuleCompileOutput D365FO.TOOLS.ModuleCompileOutput LogFile XmlLogFile D365FO.TOOLS.ModuleReportsCompileOutput D365FO.TOOLS.ModuleReportsCompileOutput LogFile XmlLogFile D365FO.TOOLS.AZCOPYTRANSFER D365FO.TOOLS.AZCOPYTRANSFER FileName File SourceUri D365FO.TOOLS.ModuleLabelGenerationOutput D365FO.TOOLS.ModuleLabelGenerationOutput OutLogFile ErrorLogFile D365FO.TOOLS.Azure.Blob D365FO.TOOLS.Azure.Blob 70 12 Right 30 Name Size LastModified D365FO.TOOLS.Environment.Service D365FO.TOOLS.Environment.Service 18 60 10 10 22 Server DisplayName Status StartType Name D365FO.TOOLS.Environment.Service.Minimal D365FO.TOOLS.Environment.Service.Minimal 70 10 10 30 DisplayName Status StartType Name D365FO.TOOLS.LCS.Environment.Operation.Status D365FO.TOOLS.LCS.Environment.Operation.Status ActivityId IsSuccess OperationActivityId ProjectId EnvironmentId ErrorMessage VersionEOL D365FO.TOOLS.LCS.Database.Operation.Status D365FO.TOOLS.LCS.Database.Operation.Status ActivityId IsSuccess OperationStatus CompletionDate OperationActivityId ProjectId EnvironmentId ErrorMessage VersionEOL D365FO.TOOLS.LCS.Deployment.Operation.Status D365FO.TOOLS.LCS.Deployment.Operation.Status ActivityId IsSuccess OperationStatus CompletionDate OperationActivityId ProjectId EnvironmentId ErrorMessage VersionEOL D365FO.TOOLS.ModelInfo D365FO.TOOLS.ModelInfo 30 30 8 13 9 Right Left ModelName Module IsBinary Customization Id Publisher D365FO.TOOLS.CompilerOutput D365FO.TOOLS.CompilerOutput Left 9 Right 9 Right File Warnings Errors D365FO.TOOLS.ModuleInfo D365FO.TOOLS.ModuleInfo 40 8 15 Left ModuleName IsBinary Version References D365FO.TOOLS.FileObject D365FO.TOOLS.FileObject Filename LastModified File D365FO.TOOLS.Bacpac.Table D365FO.TOOLS.Bacpac.Table 70 12 Right 14 Right 9 Right Name OriginalSize CompressedSize BulkFiles ================================================ FILE: d365fo.tools/xml/d365fo.tools.Types.ps1xml ================================================  Deserialized.Foo.Bar PSStandardMembers TargetTypeForDeserialization Foo.Bar Foo.Bar SerializationData PSFramework.Serialization.SerializationTypeConverter GetSerializationData PSFramework.Serialization.SerializationTypeConverter ================================================ FILE: d365fo.tools/xml/readme.md ================================================ # XML This is the folder where project XML files go, notably: - Format XML - Type Extension XML External help files should _not_ be placed in this folder! ## Notes on Files and Naming There should be only one format file and one type extension file per project, as importing them has a notable impact on import times. - The Format XML should be named `d365fo.tools.Format.ps1xml` - The Type Extension XML should be named `d365fo.tools.Types.ps1xml` ## Tools ### New-PSMDFormatTableDefinition This function will take an input object and generate format xml for an auto-sized table. It provides a simple way to get started with formats. ### Get-PSFTypeSerializationData ``` C# Warning! This section is only interest if you're using C# together with PowerShell. ``` This 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. In order for a class to be eligible for this, it needs to conform to the following rules: - Have the `[Serializable]` attribute - Be public - Have an empty constructor - Allow all public properties/fields to be set (even if setting it doesn't do anything) without throwing an exception. ``` non-public properties and fields will be lost in this process! ``` ================================================ FILE: docs/Add-D365AzureStorageConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Add-D365AzureStorageConfig ## SYNOPSIS Save an Azure Storage Account config ## SYNTAX ### AccessToken ``` Add-D365AzureStorageConfig -Name -AccountId -AccessToken -Container [-Temporary] [-Force] [] ``` ### SAS ``` Add-D365AzureStorageConfig -Name -AccountId -SAS -Container [-Temporary] [-Force] [] ``` ## DESCRIPTION Adds an Azure Storage Account config to the configuration store ## EXAMPLES ### EXAMPLE 1 ``` Add-D365AzureStorageConfig -Name "UAT-Exports" -AccountId "1234" -AccessToken "dafdfasdfasdf" -Container "testblob" ``` 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". ### EXAMPLE 2 ``` Add-D365AzureStorageConfig -Name UAT-Exports -SAS "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" -AccountId "1234" -Container "testblob" ``` 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". The SAS key enables you to provide explicit access to a given blob container inside an Azure Storage Account. The SAS key can easily be revoked and that way you have control over the access to the container and its content. ### EXAMPLE 3 ``` Add-D365AzureStorageConfig -Name UAT-Exports -SAS "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" -AccountId "1234" -Container "testblob" -Temporary ``` 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". The SAS key enables you to provide explicit access to a given blob container inside an Azure Storage Account. The SAS key can easily be revoked and that way you have control over the access to the container and its content. The configuration will only last for the rest of this PowerShell console session. ## PARAMETERS ### -Name The logical name of the Azure Storage Account you are about to registered in the configuration store ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -AccountId The account id for the Azure Storage Account you want to register in the configuration store ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -AccessToken The access token for the Azure Storage Account you want to register in the configuration store ```yaml Type: String Parameter Sets: AccessToken Aliases: Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -SAS The SAS key that you have created for the storage account or blob container ```yaml Type: String Parameter Sets: SAS Aliases: Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Container The name of the blob container inside the Azure Storage Account you want to register in the configuration store ```yaml Type: String Parameter Sets: (All) Aliases: Blobname, Blob Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Temporary Instruct the cmdlet to only temporarily add the azure storage account configuration in the configuration store ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Switch to instruct the cmdlet to overwrite already registered Azure Storage Account entry ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, Container Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Add-D365BroadcastMessageConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Add-D365BroadcastMessageConfig ## SYNOPSIS Save a broadcast message config ## SYNTAX ``` Add-D365BroadcastMessageConfig [-Name] [[-Tenant] ] [[-URL] ] [[-ClientId] ] [[-ClientSecret] ] [[-TimeZone] ] [[-EndingInMinutes] ] [-OnPremise] [-Temporary] [-Force] [] ``` ## DESCRIPTION Adds a broadcast message config to the configuration store ## EXAMPLES ### EXAMPLE 1 ``` 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" ``` This will create a new broadcast message configuration with the name "UAT". It will save "e674da86-7ee5-40a7-b777-1111111111111" as the Azure Active Directory guid. It will save "https://usnconeboxax1aos.cloud.onebox.dynamics.com" as the D365FO environment. It will save "dea8d7a9-1602-4429-b138-111111111111" as the ClientId. It will save "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522" as ClientSecret. It will use the default value "UTC" Time Zone for converting the different time and dates. It will use the default end time which is 60 minutes. ### EXAMPLE 2 ``` 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" ``` This will create a new broadcast message configuration with the name "UAT". It will target an OnPremise environment. It will save "https://adfs.local/adfs" as the OAuth Tenant Provider. It will save "https://ax-sandbox.d365fo.local" as the D365FO environment. It will save "dea8d7a9-1602-4429-b138-111111111111" as the ClientId. It will save "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522" as ClientSecret. It will use the default value "UTC" Time Zone for converting the different time and dates. It will use the default end time which is 60 minutes. ## PARAMETERS ### -Name The logical name of the broadcast configuration you are about to register in the configuration store ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Tenant Azure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to send a message to ```yaml Type: String Parameter Sets: (All) Aliases: $AADGuid Required: False Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -URL URL / URI for the D365FO environment you want to send a message to ```yaml Type: String Parameter Sets: (All) Aliases: URI Required: False Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ClientId The ClientId obtained from the Azure Portal when you created a Registered Application ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ClientSecret The ClientSecret obtained from the Azure Portal when you created a Registered Application ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -TimeZone Id of the Time Zone your environment is running in You might experience that the local VM running the D365FO is running another Time Zone than the computer you are running this cmdlet from All available .NET Time Zones can be traversed with tab for this parameter The default value is "UTC" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: UTC Accept pipeline input: False Accept wildcard characters: False ``` ### -EndingInMinutes Specify how many minutes into the future you want this message / maintenance window to last Default value is 60 minutes 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. ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: 60 Accept pipeline input: False Accept wildcard characters: False ``` ### -OnPremise Specify if environnement is an D365 OnPremise Default value is "Not set" (= Cloud Environnement) ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Temporary Instruct the cmdlet to only temporarily add the broadcast message configuration in the configuration store ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Instruct the cmdlet to overwrite the broadcast message configuration with the same name ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Servicing, Broadcast, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Clear-D365ActiveBroadcastMessageConfig]() [Get-D365ActiveBroadcastMessageConfig]() [Get-D365BroadcastMessageConfig]() [Remove-D365BroadcastMessageConfig]() [Send-D365BroadcastMessage]() [Set-D365ActiveBroadcastMessageConfig]() ================================================ FILE: docs/Add-D365ModuleToRemove.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Add-D365ModuleToRemove ## SYNOPSIS Adds a ModuleToRemove.txt file to a deployable package ## SYNTAX ``` Add-D365ModuleToRemove [-ModuleToRemove] [-DeployablePackage] [-OutputPath ] [] ``` ## DESCRIPTION Modifies an existing deployable package and adds a ModuleToRemove.txt file to it. ## EXAMPLES ### EXAMPLE 1 ``` Add-D365ModuleToRemove -ModuleToRemove "C:\temp\ModuleToRemove.txt" -DeployablePackage "C:\temp\DeployablePackage.zip" ``` 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. ### EXAMPLE 2 ``` New-D365ModuleToRemove -Path C:\Temp -Modules "MyRemovedModule1","MySecondRemovedModule" | Add-D365ModuleToRemove -DeployablePackage C:\Temp\DeployablePackage.zip ``` 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. ## PARAMETERS ### -ModuleToRemove Path to the ModuleToRemove.txt file that you want to have inside a deployable package ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -DeployablePackage Path to the deployable package file where the ModuleToRemove.txt file should be added ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputPath Path where you want the generated deployable package to be stored Default value is the same as the "DeployablePackage" parameter ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $DeployablePackage Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Florian Hopfner (@FH-Inway) ## RELATED LINKS [New-D365ModuleToRemove]() ================================================ FILE: docs/Add-D365RsatWifConfigAuthorityThumbprint.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Add-D365RsatWifConfigAuthorityThumbprint ## SYNOPSIS Add a certificate thumbprint to the wif.config. ## SYNTAX ``` Add-D365RsatWifConfigAuthorityThumbprint [-CertificateThumbprint] [] ``` ## DESCRIPTION Register a certificate thumbprint in the wif.config file. This can be useful for example when configuring RSAT on a local machine and add the used certificate thumbprint to that AOS.s ## EXAMPLES ### EXAMPLE 1 ``` Add-D365RsatWifConfigAuthorityThumbprint -CertificateThumbprint "12312323r424" ``` This will open the wif.config file and insert the "12312323r424" thumbprint value into the file. ## PARAMETERS ### -CertificateThumbprint The thumbprint value of the certificate that you want to register in the wif.config file ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: RSAT, Certificate, Testing, Regression Suite Automation Test, Regression, Test, Automation Author: Kenny Saelen (@kennysaelen) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Add-D365WindowsDefenderRules.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Add-D365WindowsDefenderRules ## SYNOPSIS Add rules to Windows Defender to enhance performance during development. ## SYNTAX ``` Add-D365WindowsDefenderRules [-Silent] [] ``` ## 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. 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. Supports rules for VS 2015 and VS 2019. ## EXAMPLES ### EXAMPLE 1 ``` Add-D365WindowsDefenderRules ``` This will add the most common rules to the Windows Defender as exceptions. All output will be written to the console. ### EXAMPLE 2 ``` Add-D365WindowsDefenderRules -Silent ``` This will add the most common rules to the Windows Defender as exceptions. All output will be silenced and not outputted to the console. ## PARAMETERS ### -Silent Instruct the cmdlet to silence the output written to the console If set the output will be silenced, if not set, the output will be written to the console ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: DevTools, Developer, Performance Author: Robin Kretzschmar (@darksmile92) Author: Mötz Jensen (@Splaxi) Author: Florian Hopfner (@FH-Inway) ## RELATED LINKS ================================================ FILE: docs/Backup-D365DevConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Backup-D365DevConfig ## SYNOPSIS Backup the DynamicsDevConfig.xml file ## SYNTAX ``` Backup-D365DevConfig [[-OutputPath] ] [-Force] [] ``` ## DESCRIPTION Will backup the DynamicsDevConfig.xml file located in the PackagesLocalDirectory\Bin folder ## EXAMPLES ### EXAMPLE 1 ``` Backup-D365DevConfig ``` Will locate the DynamicsDevConfig.xml file, and back it up. It will look for the file in the PackagesLocalDirectory\Bin folder. E.g. K:\AosService\PackagesLocalDirectory\Bin\DynamicsDevConfig.xml. It will save the file to the default location: "C:\Temp\d365fo.tools\DevConfigBackup". A result set example: Filename LastModified File -------- ------------ ---- DynamicsDevConfig.xml 6/29/2021 7:31:04 PM C:\temp\d365fo.tools\DevConfigBackup\DynamicsDevConfig.xml ### EXAMPLE 2 ``` Backup-D365DevConfig -Force ``` Will locate the DynamicsDevConfig.xml file, back it up, and overwrite if a previous backup file exists. It will look for the file in the PackagesLocalDirectory\Bin folder. E.g. K:\AosService\PackagesLocalDirectory\Bin\DynamicsDevConfig.xml. It will save the file to the default location: "C:\Temp\d365fo.tools\DevConfigBackup". It will overwrite any file named DynamicsDevConfig.xml in the destination folder. A result set example: Filename LastModified File -------- ------------ ---- DynamicsDevConfig.xml 6/29/2021 7:31:04 PM C:\temp\d365fo.tools\DevConfigBackup\DynamicsDevConfig.xml ## PARAMETERS ### -OutputPath Path to the folder where you want the DynamicsDevConfig.xml file to be persisted Default is: "C:\Temp\d365fo.tools\DevConfigBackup" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $(Join-Path $Script:DefaultTempPath "DevConfigBackup") Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Instructs the cmdlet to overwrite the destination file if it already exists ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Web Server, IIS, IIS Express, Development Author: Sander Holvoet (@smholvoet) ## RELATED LINKS ================================================ FILE: docs/Backup-D365MetaDataDir.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Backup-D365MetaDataDir ## SYNOPSIS Create a backup of the Metadata directory ## SYNTAX ``` Backup-D365MetaDataDir [[-MetaDataDir] ] [[-BackupDir] ] [] ``` ## DESCRIPTION Creates a backup of all the files and folders from the Metadata directory ## EXAMPLES ### EXAMPLE 1 ``` Backup-D365MetaDataDir ``` This will backup the PackagesLocalDirectory and create an PackagesLocalDirectory_backup next to it ## PARAMETERS ### -MetaDataDir Path to the Metadata directory Default value is the PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:MetaDataDir" Accept pipeline input: False Accept wildcard characters: False ``` ### -BackupDir Path where you want the backup to be place ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$($Script:MetaDataDir)_backup" Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: PackagesLocalDirectory, MetaData, MetaDataDir, MeteDataDirectory, Backup, Development Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Backup-D365Runbook.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Backup-D365Runbook ## SYNOPSIS Backup a runbook file ## SYNTAX ``` Backup-D365Runbook [-File] [[-DestinationPath] ] [-Force] [] ``` ## DESCRIPTION Backup a runbook file for you to persist it for later analysis ## EXAMPLES ### EXAMPLE 1 ``` Backup-D365Runbook -File "C:\DynamicsAX\InstallationRecords\Runbooks\Runbook_20190327.xml" ``` This will backup the "C:\DynamicsAX\InstallationRecords\Runbooks\Runbook_20190327.xml". The default destination folder is used, "c:\temp\d365fo.tools\runbookbackups\". ### EXAMPLE 2 ``` Backup-D365Runbook -File "C:\DynamicsAX\InstallationRecords\Runbooks\Runbook_20190327.xml" -Force ``` This will backup the "C:\DynamicsAX\InstallationRecords\Runbooks\Runbook_20190327.xml". The default destination folder is used, "c:\temp\d365fo.tools\runbookbackups\". If the file already exists in the destination folder, it will be overwritten. ### EXAMPLE 3 ``` Get-D365Runbook | Backup-D365Runbook ``` This will backup all runbook files found with the "Get-D365Runbook" cmdlet. The default destination folder is used, "c:\temp\d365fo.tools\runbookbackups\". ## PARAMETERS ### -File Path to the file you want to backup ```yaml Type: String Parameter Sets: (All) Aliases: Path Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -DestinationPath Path to the folder where you want the backup file to be placed ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $(Join-Path $Script:DefaultTempPath "RunbookBackups") Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Instructs the cmdlet to overwrite the destination file if it already exists ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Runbook, Backup, Analysis Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Backup-D365WebConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Backup-D365WebConfig ## SYNOPSIS Backup the web.config file ## SYNTAX ``` Backup-D365WebConfig [[-OutputPath] ] [-Force] [] ``` ## DESCRIPTION Will backup the web.config file located in the AOS / IIS folder ## EXAMPLES ### EXAMPLE 1 ``` Backup-D365WebConfig ``` Will locate the web.config file, and back it up. It will look for the file in the AOS / IIS folder. E.g. K:\AosService\WebRoot\web.config. It will save the file to the default location: "C:\Temp\d365fo.tools\WebConfigBackup". A result set example: Filename LastModified File -------- ------------ ---- web.config 6/29/2021 7:31:04 PM C:\temp\d365fo.tools\WebConfigBackup\web.config ### EXAMPLE 2 ``` Backup-D365WebConfig -Force ``` Will locate the web.config file, back it up, and overwrite if a previous backup file exists. It will look for the file in the AOS / IIS folder. E.g. K:\AosService\WebRoot\web.config. It will save the file to the default location: "C:\Temp\d365fo.tools\WebConfigBackup". It will overwrite any file named web.config in the destination folder. A result set example: Filename LastModified File -------- ------------ ---- web.config 6/29/2021 7:31:04 PM C:\temp\d365fo.tools\WebConfigBackup\web.config ## PARAMETERS ### -OutputPath Path to the folder where you want the web.config file to be persisted Default is: "C:\Temp\d365fo.tools\WebConfigBackup" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $(Join-Path $Script:DefaultTempPath "WebConfigBackup") Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Instructs the cmdlet to overwrite the destination file if it already exists ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Backup-D365WifConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Backup-D365WifConfig ## SYNOPSIS Backup the wif.config file ## SYNTAX ``` Backup-D365WifConfig [[-OutputPath] ] [-Force] [] ``` ## DESCRIPTION Will backup the wif.config file located in the AOS / IIS folder ## EXAMPLES ### EXAMPLE 1 ``` Backup-D365WifConfig ``` Will locate the wif.config file, and back it up. It will look for the file in the AOS / IIS folder. E.g. K:\AosService\WebRoot\wif.config. It will save the file to the default location: "C:\Temp\d365fo.tools\WifConfigBackup". A result set example: Filename LastModified File -------- ------------ ---- wif.config 6/29/2021 7:31:04 PM C:\temp\d365fo.tools\WifConfigBackup\wif.config ### EXAMPLE 2 ``` Backup-D365WifConfig -Force ``` Will locate the wif.config file, back it up, and overwrite if a previous backup file exists. It will look for the file in the AOS / IIS folder. E.g. K:\AosService\WebRoot\wif.config. It will save the file to the default location: "C:\Temp\d365fo.tools\WifConfigBackup". It will overwrite any file named wif.config in the destination folder. A result set example: Filename LastModified File -------- ------------ ---- wif.config 6/29/2021 7:31:04 PM C:\temp\d365fo.tools\WifConfigBackup\wif.config ## PARAMETERS ### -OutputPath Path to the folder where you want the web.config file to be persisted Default is: "C:\Temp\d365fo.tools\WifConfigBackup" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $(Join-Path $Script:DefaultTempPath "WifConfigBackup") Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Instructs the cmdlet to overwrite the destination file if it already exists ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Florian Hopfner (@FH-Inway) ## RELATED LINKS ================================================ FILE: docs/Clear-D365ActiveBroadcastMessageConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Clear-D365ActiveBroadcastMessageConfig ## SYNOPSIS Clear the active broadcast message config ## SYNTAX ``` Clear-D365ActiveBroadcastMessageConfig [-Temporary] [] ``` ## DESCRIPTION Clear the active broadcast message config from the configuration store ## EXAMPLES ### EXAMPLE 1 ``` Clear-D365ActiveBroadcastMessageConfig ``` This will clear the active broadcast message configuration from the configuration store. ## PARAMETERS ### -Temporary Instruct the cmdlet to only temporarily clear the active broadcast message configuration in the configuration store ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Servicing, Broadcast, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Add-D365BroadcastMessageConfig]() [Get-D365ActiveBroadcastMessageConfig]() [Get-D365BroadcastMessageConfig]() [Remove-D365BroadcastMessageConfig]() [Send-D365BroadcastMessage]() [Set-D365ActiveBroadcastMessageConfig]() ================================================ FILE: docs/Clear-D365BacpacObject.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Clear-D365BacpacObject ## SYNOPSIS Clear out sql objects from inside the bacpac/dacpac or zip file ## SYNTAX ### Copy (Default) ``` Clear-D365BacpacObject -Path -Name [-ObjectType ] -OutputPath [] ``` ### Keep ``` Clear-D365BacpacObject -Path -Name [-ObjectType ] [-ClearFromSource] [] ``` ## 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 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 The default behavior is that you get a copy of the file, where the desired sql objects are removed ## EXAMPLES ### EXAMPLE 1 ``` Clear-D365BacpacObject -Path "C:\Temp\AxDB.bacpac" -ObjectType SqlView -Name "View2" -OutputPath "C:\Temp\AXBD_Cleaned.bacpac" ``` This will remove the SqlView "View2" from inside the bacpac file. It uses "C:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "View2" as the name of the object to delete. It uses "C:\Temp\AXBD_Cleaned.bacpac" as the OutputPath to where it will store the updated bacpac file. ### EXAMPLE 2 ``` Clear-D365BacpacObject -Path "C:\Temp\AxDB.bacpac" -ObjectType SqlView -Name "dbo.View1","View2" -OutputPath "C:\Temp\AXBD_Cleaned.bacpac" ``` This will remove the SqlView(s) "dbo.View1" and "View2" from inside the bacpac file. It uses "C:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "dbo.View1","View2" as the names of objects to delete. It uses "C:\Temp\AXBD_Cleaned.bacpac" as the OutputPath to where it will store the updated bacpac file. ### EXAMPLE 3 ``` Clear-D365BacpacObject -Path "C:\Temp\AxDB.bacpac" -ObjectType SqlIndex -Name "[dbo].[SalesTable].[CustomIndexName1]" -ClearFromSource ``` This will remove the SqlIndex "CustomIndexName1" from the dbo.SalesTable table from inside the bacpac file. It uses "C:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "\[dbo\].\[SalesTable\].\[CustomIndexName1\]" as the name of the object to delete. Caution: 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. ## PARAMETERS ### -Path Path to the bacpac/dacpac or zip file that you want to work against ```yaml Type: String Parameter Sets: (All) Aliases: BacpacFile, File Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Name Name of the sql object that you want to remove Supports an array of names If a schema name isn't supplied as part of the table name, the cmdlet will prefix it with "dbo." Some sql objects are 3 part named, which will require that you fill them in with brackets E.g. \[dbo\].\[SalesTable\].\[CustomIndexName1\] - Index - Constraints ```yaml Type: String[] Parameter Sets: (All) Aliases: ObjectName Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ObjectType Instruct the cmdlet, the type of object that you want to remove As we are manipulating the bacpac file, we can only handle 1 ObjectType per run If you want to remove SqlView and SqlIndex, you will have to run the cmdlet 1 time for SqlViews and 1 time for SqlIndex Supported types are: "SqlView", "SqlTable", "SqlIndex", "SqlCheckConstraint" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputPath Path to where you want the updated bacpac/dacpac or zip file to be saved ```yaml Type: String Parameter Sets: Copy Aliases: Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ClearFromSource Instruct the cmdlet to delete sql objects directly from the source file 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 ```yaml Type: SwitchParameter Parameter Sets: Keep Aliases: Required: True Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES It will NOT fail, if it can't find any object with the specified name ## RELATED LINKS ================================================ FILE: docs/Clear-D365BacpacTableData.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Clear-D365BacpacTableData ## SYNOPSIS Clear out data for a table inside the bacpac/dacpac or zip file ## SYNTAX ### Copy (Default) ``` Clear-D365BacpacTableData -Path -Table -OutputPath [] ``` ### Keep ``` Clear-D365BacpacTableData -Path -Table [-ClearFromSource] [] ``` ## DESCRIPTION Remove all data for a table inside a bacpac/dacpac or zip file, before restoring it into your SQL Server / Azure SQL DB It will open the file as a zip archive, locate the desired table and remove the data that otherwise would have been loaded The default behavior is that you get a copy of the file, where the desired data is removed ## EXAMPLES ### EXAMPLE 1 ``` Clear-D365BacpacTableData -Path "C:\Temp\AxDB.bacpac" -Table "BATCHJOBHISTORY" -OutputPath "C:\Temp\AXBD_Cleaned.bacpac" ``` This will remove the data from the BatchJobHistory table from inside the bacpac file. It uses "C:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "BATCHJOBHISTORY" as the Table to delete data from. It uses "C:\Temp\AXBD_Cleaned.bacpac" as the OutputPath to where it will store the updated bacpac file. ### EXAMPLE 2 ``` Clear-D365BacpacTableData -Path "C:\Temp\AxDB.bacpac" -Table "dbo.BATCHHISTORY","BATCHJOBHISTORY" -OutputPath "C:\Temp\AXBD_Cleaned.bacpac" ``` This will remove the data from the dbo.BatchHistory and BatchJobHistory table from inside the bacpac file. It uses "C:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "dbo.BATCHHISTORY","BATCHJOBHISTORY" as the Table to delete data from. It uses "C:\Temp\AXBD_Cleaned.bacpac" as the OutputPath to where it will store the updated bacpac file. ### EXAMPLE 3 ``` Clear-D365BacpacTableData -Path "C:\Temp\AxDB.bacpac" -Table "dbo.BATCHHISTORY","BATCHJOBHISTORY" -ClearFromSource ``` This will remove the data from the dbo.BatchHistory and BatchJobHistory table from inside the bacpac file. It uses "C:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "dbo.BATCHHISTORY","BATCHJOBHISTORY" as the Table to delete data from. Caution: 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. ### EXAMPLE 4 ``` Clear-D365BacpacTableData -Path "C:\Temp\AxDB.bacpac" -Table "CustomTableNameThatDoesNotExists","BATCHJOBHISTORY" -OutputPath "C:\Temp\AXBD_Cleaned.bacpac" -ErrorAction SilentlyContinue ``` This will remove the data from the BatchJobHistory table from inside the bacpac file. It uses "C:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "CustomTableNameThatDoesNotExists","BATCHJOBHISTORY" as the Table to delete data from. It respects the respects the ErrorAction "SilentlyContinue", and will continue removing tables from the bacpac file, even when some tables are missing. It uses "C:\Temp\AXBD_Cleaned.bacpac" as the OutputPath to where it will store the updated bacpac file. ## PARAMETERS ### -Path Path to the bacpac/dacpac or zip file that you want to work against ```yaml Type: String Parameter Sets: (All) Aliases: BacpacFile, File Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Table Name of the table that you want to delete the data for Supports an array of table names If a schema name isn't supplied as part of the table name, the cmdlet will prefix it with "dbo." Supports wildcard searching e.g. "Sales*" will delete all "dbo.Sales*" tables in the bacpac file ```yaml Type: String[] Parameter Sets: (All) Aliases: TableName Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputPath Path to where you want the updated bacpac/dacpac or zip file to be saved ```yaml Type: String Parameter Sets: Copy Aliases: Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ClearFromSource Instruct the cmdlet to delete tables directly from the source file 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 ```yaml Type: SwitchParameter Parameter Sets: Keep Aliases: Required: True Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Bacpac, Servicing, Data, Deletion, SqlPackage Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Clear-D365MonitorData.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Clear-D365MonitorData ## SYNOPSIS Clear the monitoring data from a Dynamics 365 for Finance & Operations machine ## SYNTAX ``` Clear-D365MonitorData [[-Path] ] [] ``` ## DESCRIPTION Clear the monitoring data that is filling up the service drive on a Dynamics 365 for Finance & Operations ## EXAMPLES ### EXAMPLE 1 ``` Clear-D365MonitorData ``` This will delete all the files that are located in the default path on the machine. Some files might be locked by a process, but the cmdlet will attemp to delete all files. ## PARAMETERS ### -Path The path to where the monitoring data is located The default value is the "ServiceDrive" (j:\ | k:\\) and the \MonAgentData\SingleAgent\Tables folder structure ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: (Join-Path $script:ServiceDrive "\MonAgentData\SingleAgent\Tables") Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Monitor, MonitorData, MonitorAgent, CleanUp, Servicing Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Clear-D365TempDbTables.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: https://msdyn365fo.wordpress.com/2019/12/18/cleanup-tempdb-tables-in-a-msdyn365fo-sandbox-environment/ schema: 2.0.0 --- # Clear-D365TempDbTables ## SYNOPSIS Cleanup TempDB tables in Microsoft Dynamics 365 for Finance and Operations environment ## SYNTAX ``` Clear-D365TempDbTables [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-Days] ] [-EnableException] [] ``` ## DESCRIPTION This will cleanup X days of TempDB tables The reason behind this process is that sp_updatestats takes significantly longer depending on the number of TempDB tables in the system ## EXAMPLES ### EXAMPLE 1 ``` Clear-D365TempDbTables -Days 7 ``` This will cleanup old tempdb tables. It will use 7 as the Days parameter. The remaining parameters will use their default values, which are provided by the tools. ## PARAMETERS ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -Days Temp tables older than this Days input will be dropped The default value is 7 (days) ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: 7 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Alex Kwitny (@AlexOnDAX) Author: Mötz Jensen (@Splaxi) This cmdlet is based on the findings from Paul Heisterkamp (@braul) See his blog for more info: https://msdyn365fo.wordpress.com/2019/12/18/cleanup-tempdb-tables-in-a-msdyn365fo-sandbox-environment/ ## RELATED LINKS [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/) [https://github.com/PaulHeisterkamp/d365fo.blog/blob/master/Tools/SQL/DropTempDBTables.sql](https://github.com/PaulHeisterkamp/d365fo.blog/blob/master/Tools/SQL/DropTempDBTables.sql) ================================================ FILE: docs/ConvertTo-D365Dacpac.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: https://msdyn365fo.wordpress.com/2019/12/18/cleanup-tempdb-tables-in-a-msdyn365fo-sandbox-environment/ schema: 2.0.0 --- # ConvertTo-D365Dacpac ## SYNOPSIS Convert bacpac file to dacpac ## SYNTAX ``` ConvertTo-D365Dacpac [-Path] [] ``` ## DESCRIPTION Convert bacpac file to dacpac It will extract the origin.xml file from the file, and set the \false\ for the file to be valid to be used as a dacpac file ## EXAMPLES ### EXAMPLE 1 ``` ConvertTo-D365Dacpac -Path "C:\Temp\AxDB.bacpac" ``` This will convert the bacpac file into a dacpac file. It will extract the origin.xml file, update it and apply it to the file. It will rename the file into a dacpac. The source file will be manipulated, so be careful to have an extra copy of the file. ## PARAMETERS ### -Path Path to the bacpac file that you want to work against It can also be a zip file ```yaml Type: String Parameter Sets: (All) Aliases: BacpacFile, File Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Bacpac, Servicing, Data, SqlPackage, Dacpac, Table Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Disable-D365Exception.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Disable-D365Exception ## SYNOPSIS Disables throwing of exceptions ## SYNTAX ``` Disable-D365Exception [] ``` ## DESCRIPTION Restore the default exception behavior of the module to not support throwing exceptions Useful when the default behavior was changed with Enable-D365Exception and the default behavior should be restored ## EXAMPLES ### EXAMPLE 1 ``` Disable-D365Exception ``` This will restore the default behavior of the module to not support throwing exceptions. ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Exception, Exceptions, Warning, Warnings Author: Florian Hopfner (@FH-Inway) ## RELATED LINKS [Enable-D365Exception]() ================================================ FILE: docs/Disable-D365Flight.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online 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 schema: 2.0.0 --- # Disable-D365Flight ## SYNOPSIS Used to disable a flight ## SYNTAX ``` Disable-D365Flight [-FlightName] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [] ``` ## DESCRIPTION Provides a method for disabling a flight in D365FO. ## EXAMPLES ### EXAMPLE 1 ``` Disable-D365Flight -FlightName DMFEnableAllCompanyExport ``` Disables the flight DMFEnableAllCompanyExport ## PARAMETERS ### -FlightName Name of the flight to disable ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Flight, Flighting Author: Frank Hüther (@FrankHuether) The DataAccess.FlightingServiceCatalogID must already be set in the web.config file. At no circumstances can this cmdlet be used to enable a flight in a PROD environment. ## RELATED 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](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) ================================================ FILE: docs/Disable-D365IISPreload.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Disable-D365IISPreload ## SYNOPSIS Disables IIS Preload for the AOSService application pool and website. ## SYNTAX ``` Disable-D365IISPreload [] ``` ## DESCRIPTION Reverts IIS Preload settings for the AOSService application: - Sets Application Pool Start Mode to OnDemand - Sets Idle Time-out to 0 (default) - Disables Preload on the AOSService website - Sets doAppInitAfterRestart to false (if Application Initialization is installed) - Restores previous IIS Preload configuration from backup if available - Restores or removes the initializationPage property as appropriate - Uninstalls IIS Application Initialization feature if it was not installed in the backup ## EXAMPLES ### EXAMPLE 1 ``` Disable-D365IISPreload ``` Disables IIS Preload for the AOSService application pool and website, restoring previous settings from backup if available. ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Florian Hopfner (FH-Inway) 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) Written with GitHub Copilot GPT-4.1, mostly in agent mode. See commits for prompts. ## RELATED LINKS [Get-D365IISPreload]() [Enable-D365IISPreload]() ================================================ FILE: docs/Disable-D365MaintenanceMode.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Disable-D365MaintenanceMode ## SYNOPSIS Sets the environment back into operating state ## SYNTAX ``` Disable-D365MaintenanceMode [[-MetaDataDir] ] [[-BinDir] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-LogPath] ] [-ShowOriginalProgress] [-OutputCommandOnly] [] ``` ## DESCRIPTION Sets the Dynamics 365 environment back into operating / running state after it has been in maintenance mode. ## EXAMPLES ### EXAMPLE 1 ``` Disable-D365MaintenanceMode ``` 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. ### EXAMPLE 2 ``` Disable-D365MaintenanceMode -ShowOriginalProgress ``` 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. The output from stopping the services will be written to the console / host. The output from the "deployment" process will be written to the console / host. The output from starting the services will be written to the console / host. ## PARAMETERS ### -MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: "$Script:MetaDataDir" Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir" Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 7 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\MaintenanceMode") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable or SQL script and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: MaintenanceMode, Maintenance, License, Configuration, Servicing Author: Mötz Jensen (@splaxi) Author: Tommy Skaue (@skaue) On VHD based environments with administrator privileges: The cmdlet wraps the execution of Microsoft.Dynamics.AX.Deployment.Setup.exe and parses the parameters needed. Without administrator privileges or on cloud hosted environments: Will stop all services, execute a SQL script and start all services. ## RELATED LINKS [Enable-D365MaintenanceMode]() [Get-D365MaintenanceMode]() ================================================ FILE: docs/Disable-D365SqlChangeTracking.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Disable-D365SqlChangeTracking ## SYNOPSIS Disable Change Tracking for the environment ## SYNTAX ``` Disable-D365SqlChangeTracking [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [-EnableException] [] ``` ## DESCRIPTION Disables the SQL Server Change Tracking for the environments database and all tables inside the database ## EXAMPLES ### EXAMPLE 1 ``` Disable-D365SqlChangeTracking ``` This will disable the Change Tracking on the Sql Server. ## PARAMETERS ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: MaintenanceMode, Maintenance, License, Configuration, Servicing Author: Mötz Jensen (@splaxi) ## RELATED LINKS ================================================ FILE: docs/Disable-D365User.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Disable-D365User ## SYNOPSIS Disables the user in D365FO ## SYNTAX ``` Disable-D365User [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-Email] ] [] ``` ## DESCRIPTION Sets the enabled to 0 in the userinfo table. ## EXAMPLES ### EXAMPLE 1 ``` Disable-D365User ``` This will Disable all users for the environment ### EXAMPLE 2 ``` Disable-D365User -Email "claire@contoso.com" ``` This will Disable the user with the email address "claire@contoso.com" ### EXAMPLE 3 ``` Disable-D365User -Email "*contoso.com" ``` This will Disable all users that matches the search "*contoso.com" in their email address ## PARAMETERS ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -Email The search string to select which user(s) should be disabled. The parameter supports wildcards. E.g. -Email "*@contoso.com*" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: * Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: User, Users, Security, Configuration, Permission Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Enable-D365Exception.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Enable-D365Exception ## SYNOPSIS Enable exceptions to be thrown ## SYNTAX ``` Enable-D365Exception [] ``` ## DESCRIPTION Change the default exception behavior of the module to support throwing exceptions Useful when the module is used in an automated fashion, like inside Azure DevOps pipelines and large PowerShell scripts ## EXAMPLES ### EXAMPLE 1 ``` Enable-D365Exception ``` This will for the rest of the current PowerShell session make sure that exceptions will be thrown. ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Exception, Exceptions, Warning, Warnings Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Disable-D365Exception]() ================================================ FILE: docs/Enable-D365Flight.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Enable-D365Flight ## SYNOPSIS Used to enable a flight ## SYNTAX ``` Enable-D365Flight [-FlightName] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [] ``` ## DESCRIPTION Provides a method for enabling a flight in D365FO. ## EXAMPLES ### EXAMPLE 1 ``` Enable-D365Flight -FlightName DMFEnableAllCompanyExport ``` Enables the flight DMFEnableAllCompanyExport ## PARAMETERS ### -FlightName Name of the flight to enable ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Flight, Flighting Author: Frank Hüther (@FrankHuether) The DataAccess.FlightingServiceCatalogID must already be set in the web.config file. 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 At no circumstances can this cmdlet be used to enable a flight in a PROD environment. ## RELATED LINKS ================================================ FILE: docs/Enable-D365IISPreload.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Enable-D365IISPreload ## SYNOPSIS Enables IIS Preload for the AOSService application pool and website. ## SYNTAX ``` Enable-D365IISPreload [[-BaseUrl] ] [] ``` ## DESCRIPTION Configures IIS to preload the AOSService application, improving startup time after X++ compile. - Sets Application Pool Start Mode to AlwaysRunning - Sets Idle Time-out to 0 - Enables Preload on the AOSService website - Sets doAppInitAfterRestart to true (if Application Initialization is installed) - Optionally sets the initializationPage to a custom base URL ## EXAMPLES ### EXAMPLE 1 ``` Enable-D365IISPreload ``` This will enable IIS Preload and set the initializationPage using the automatically detected base URL. ### EXAMPLE 2 ``` Enable-D365IISPreload -BaseUrl "https://usnconeboxax1aos.cloud.onebox.dynamics.com" ``` This will enable IIS Preload and set the initializationPage to https://usnconeboxax1aos.cloud.onebox.dynamics.com/?mi=DefaultDashboard ## PARAMETERS ### -BaseUrl The base URL to use for the initializationPage setting in IIS Application Initialization. If not provided, the function will attempt to determine the base URL automatically using Get-D365Url. Example: https://usnconeboxax1aos.cloud.onebox.dynamics.com ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Florian Hopfner (FH-Inway) 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) Written with GitHub Copilot GPT-4.1, mostly in agent mode. See commits for prompts. ## RELATED LINKS [Get-D365IISPreload]() [Disable-D365IISPreload]() ================================================ FILE: docs/Enable-D365MaintenanceMode.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Enable-D365MaintenanceMode ## SYNOPSIS Sets the environment into maintenance mode ## SYNTAX ``` Enable-D365MaintenanceMode [[-MetaDataDir] ] [[-BinDir] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-LogPath] ] [-ShowOriginalProgress] [-OutputCommandOnly] [] ``` ## DESCRIPTION Sets the Dynamics 365 environment into maintenance mode to enable the user to update the license configuration ## EXAMPLES ### EXAMPLE 1 ``` Enable-D365MaintenanceMode ``` 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. ### EXAMPLE 2 ``` Enable-D365MaintenanceMode -ShowOriginalProgress ``` 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. The output from stopping the services will be written to the console / host. The output from the "deployment" process will be written to the console / host. The output from starting the services will be written to the console / host. ## PARAMETERS ### -MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: "$Script:MetaDataDir" Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir" Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 7 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\MaintenanceMode") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable or SQL script and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: MaintenanceMode, Maintenance, License, Configuration, Servicing Author: Mötz Jensen (@splaxi) Author: Tommy Skaue (@skaue) On VHD based environments with administrator privileges: The cmdlet wraps the execution of Microsoft.Dynamics.AX.Deployment.Setup.exe and parses the parameters needed. Without administrator privileges or on cloud hosted environments: Will stop all services, execute a SQL script and starts the AOS service (other services are not needed during maintenance mode). ## RELATED LINKS [Get-D365MaintenanceMode]() [Disable-D365MaintenanceMode]() ================================================ FILE: docs/Enable-D365SqlChangeTracking.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Enable-D365SqlChangeTracking ## SYNOPSIS Enable Change Tracking for the environment ## SYNTAX ``` Enable-D365SqlChangeTracking [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [-EnableException] [] ``` ## DESCRIPTION Enable the SQL Server Change Tracking for the environments database It is a requirement for the Data Entities refresh to be able to complete correctly ## EXAMPLES ### EXAMPLE 1 ``` Enable-D365SqlChangeTracking ``` This will enable the Change Tracking on the Sql Server. ## PARAMETERS ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: MaintenanceMode, Maintenance, License, Configuration, Servicing Author: Mötz Jensen (@splaxi) ## RELATED LINKS ================================================ FILE: docs/Enable-D365User.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Enable-D365User ## SYNOPSIS Enables the user in D365FO ## SYNTAX ``` Enable-D365User [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-Email] ] [] ``` ## DESCRIPTION Sets the enabled to 1 in the userinfo table ## EXAMPLES ### EXAMPLE 1 ``` Enable-D365User ``` This will enable all users for the environment ### EXAMPLE 2 ``` Enable-D365User -Email "claire@contoso.com" ``` This will enable the user with the email address "claire@contoso.com" ### EXAMPLE 3 ``` Enable-D365User -Email "*contoso.com" ``` This will enable all users that matches the search "*contoso.com" in their email address ## PARAMETERS ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -Email The search string to select which user(s) should be enabled The parameter supports wildcards. E.g. -Email "*@contoso.com*" Default value is "*" to update all users ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: * Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: User, Users, Security, Configuration, Permission Author: Mötz Jensen ## RELATED LINKS ================================================ FILE: docs/Export-D365BacpacModelFile.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Export-D365BacpacModelFile ## SYNOPSIS Extract the "model.xml" from the bacpac file ## SYNTAX ``` Export-D365BacpacModelFile [-Path] [[-OutputPath] ] [-Force] [] ``` ## DESCRIPTION Extract the "model.xml" file from inside the bacpac file 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 ## EXAMPLES ### EXAMPLE 1 ``` Export-D365BacpacModelFile -Path "c:\Temp\AxDB.bacpac" ``` This will extract the "model.xml" file from inside the bacpac file. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "c:\temp\d365fo.tools" as the OutputPath to where it will store the extracted "bacpac.model.xml" file. ### EXAMPLE 2 ``` Export-D365BacpacModelFile -Path "c:\Temp\AxDB.bacpac" -OutputPath "c:\Temp\model.xml" -Force ``` This will extract the "model.xml" file from inside the bacpac file. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses "c:\Temp\model.xml" as the OutputPath to where it will store the extracted "model.xml" file. It will override the "c:\Temp\model.xml" if already present. ### EXAMPLE 3 ``` Export-D365BacpacModelFile -Path "c:\Temp\AxDB.bacpac" | Get-D365BacpacSqlOptions ``` This will display all the SQL Server options configured in the bacpac file. First it will export the bacpac.model.xml from the "c:\Temp\AxDB.bacpac" file, using the Export-D365BacpacModelFile function. The output from Export-D365BacpacModelFile will be piped into the Get-D365BacpacSqlOptions function. ## PARAMETERS ### -Path Path to the bacpac file that you want to work against It can also be a zip file ```yaml Type: String Parameter Sets: (All) Aliases: BacpacFile, File Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputPath Path to where you want the updated bacpac file to be saved Default value is: "c:\temp\d365fo.tools" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Switch to instruct the cmdlet to overwrite the "model.xml" specified in the OutputPath ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Bacpac, Servicing, Data, SqlPackage, Sql Server Options, Collation Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Export-D365Model.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Export-D365Model ## SYNOPSIS Export a model from Dynamics 365 for Finance & Operations ## SYNTAX ``` Export-D365Model [-Path] [-Model] [-Force] [[-BinDir] ] [[-MetaDataDir] ] [[-LogPath] ] [-ShowOriginalProgress] [-OutputCommandOnly] [] ``` ## DESCRIPTION Export a model from a Dynamics 365 for Finance & Operations environment ## EXAMPLES ### EXAMPLE 1 ``` Export-D365Model -Path c:\temp\d365fo.tools -Model CustomModelName ``` This will export the "CustomModelName" model from the default PackagesLocalDirectory path. It export the model to the "c:\temp\d365fo.tools" location. ## PARAMETERS ### -Path Path to the folder where you want to save the model file ```yaml Type: String Parameter Sets: (All) Aliases: File Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Model Name of the model that you want to work against ```yaml Type: String Parameter Sets: (All) Aliases: Modelname Required: True Position: 2 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Force Instruct the cmdlet to overwrite already existing file ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: "$Script:PackageDirectory\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: "$Script:MetaDataDir" Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 5 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ModelUtilExport") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: ModelUtil, Axmodel, Model, Export Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Export-D365SecurityDetails.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Export-D365SecurityDetails ## SYNOPSIS Extract details from a User Interface Security file ## SYNTAX ``` Export-D365SecurityDetails [-FilePath] [[-OutputDirectory] ] [] ``` ## DESCRIPTION Extracts and partitions the security details from an User Interface Security file into the same structure as AOT security files ## EXAMPLES ### EXAMPLE 1 ``` Export-D365SecurityDetails -FilePath C:\temp\d365fo.tools\SecurityDatabaseCustomizations.xml ``` 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" ## PARAMETERS ### -FilePath Path to the User Interface Security XML file you want to work against ```yaml Type: String Parameter Sets: (All) Aliases: Path Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputDirectory Path to the folder where the cmdlet will output and structure the details from the file. The cmdlet will create a sub folder named like the input file. Default value is: "C:\temp\d365fo.tools\security-extraction" ```yaml Type: String Parameter Sets: (All) Aliases: Output Required: False Position: 2 Default value: C:\temp\d365fo.tools\security-extraction Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Security, Configuration, Permission, Development Author: Mötz Jensen (@splaxi) The work and design of this cmdlet is based on the findings by Alex Meyer (@alexmeyer_ITGuy). He wrote about his findings on his blog: https://alexdmeyer.com/2018/09/26/converting-d365fo-user-interface-security-customizations-export-to-aot-security-xml-files/ He published a github repository: https://github.com/ameyer505/D365FOSecurityConverter All credits goes to Alex Meyer ## RELATED LINKS ================================================ FILE: docs/Find-D365Command.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Find-D365Command ## SYNOPSIS Finds d365fo.tools commands searching through the inline help text ## SYNTAX ``` Find-D365Command [[-Pattern] ] [[-Tag] ] [[-Author] ] [[-MinimumVersion] ] [[-MaximumVersion] ] [-Rebuild] [-EnableException] [-WhatIf] [-Confirm] [] ``` ## 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 ## EXAMPLES ### EXAMPLE 1 ``` Find-D365Command "snapshot" ``` For lazy typers: finds all commands searching the entire help for "snapshot" ### EXAMPLE 2 ``` Find-D365Command -Pattern "snapshot" ``` For rigorous typers: finds all commands searching the entire help for "snapshot" ### EXAMPLE 3 ``` Find-D365Command -Tag copy ``` Finds all commands tagged with "copy" ### EXAMPLE 4 ``` Find-D365Command -Tag copy,user ``` Finds all commands tagged with BOTH "copy" and "user" ### EXAMPLE 5 ``` Find-D365Command -Author Mötz ``` Finds every command whose author contains "Mötz" ### EXAMPLE 6 ``` Find-D365Command -Author Mötz -Tag copy ``` Finds every command whose author contains "Mötz" and it tagged as "copy" ### EXAMPLE 7 ``` Find-D365Command -Pattern snapshot -Rebuild ``` Finds all commands searching the entire help for "snapshot", rebuilding the index (good for developers) ## PARAMETERS ### -Pattern Searches help for all commands in d365fo.tools for the specified pattern and displays all results ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Tag Finds all commands tagged with this auto-populated tag ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Author Finds all commands tagged with this author ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -MinimumVersion Finds all commands tagged with this auto-populated minimum version ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -MaximumVersion Finds all commands tagged with this auto-populated maximum version ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Rebuild Rebuilds the index ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException By default, when something goes wrong we try to catch it, interpret it and give you a friendly warning message. This avoids overwhelming you with "sea of red" exceptions, but is inconvenient because it basically disables advanced scripting. Using this switch turns this "nice by default" feature off and enables you to catch exceptions with your own try/catch. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Silent Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf Displays what would happen if the command is run ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Confirm Confirms overwrite of index ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Find, Help, Command Author: Mötz Jensen (@Splaxi) License: MIT https://opensource.org/licenses/MIT This cmdlet / function is copy & paste implementation based on the Find-DbaCommand from the dbatools.io project Original author: Simone Bizzotto (@niphold) ## RELATED LINKS ================================================ FILE: docs/Get-D365AOTObject.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365AOTObject ## SYNOPSIS Search for AOT object ## SYNTAX ``` Get-D365AOTObject [-Path] [[-ObjectType] ] [[-Name] ] [-SearchInPackages] [-IncludePath] [] ``` ## DESCRIPTION Enables you to search for different AOT objects ## EXAMPLES ### EXAMPLE 1 ``` Get-D365AOTObject -Name *flush* -ObjectType AxClass -Path "C:\AOSService\PackagesLocalDirectory\ApplicationFoundation" ``` This will search inside the ApplicationFoundation package for all AxClasses that matches the search *flush*. ### EXAMPLE 2 ``` Get-D365AOTObject -Name *flush* -ObjectType AxClass -IncludePath -Path "C:\AOSService\PackagesLocalDirectory\ApplicationFoundation" ``` This will search inside the ApplicationFoundation package for all AxClasses that matches the search *flush* and include the full path to the files. ### EXAMPLE 3 ``` Get-D365InstalledPackage -Name Application* | Get-D365AOTObject -Name *flush* -ObjectType AxClass ``` 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*. ### EXAMPLE 4 ``` Get-D365AOTObject -Path "C:\AOSService\PackagesLocalDirectory\*" -Name *flush* -ObjectType AxClass -SearchInPackages ``` This is an advanced example and shouldn't be something you resolve to every time. This will search across all packages and will look for the all AxClasses that matches the search *flush*. It will NOT search in the XppMetaData directory for each package. This can stress your system. ## PARAMETERS ### -Path Path to the package that you want to work against ```yaml Type: String Parameter Sets: (All) Aliases: PackageDirectory Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -ObjectType The type of AOT object you're searching for ```yaml Type: String[] Parameter Sets: (All) Aliases: Type Required: False Position: 2 Default value: @("AxClass") Accept pipeline input: False Accept wildcard characters: False ``` ### -Name Name of the object that you're looking for Accepts wildcards for searching. E.g. -Name "Work*status" Default value is "*" which will search for all objects ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -SearchInPackages Switch to instruct the cmdlet to search in packages directly instead of searching in the XppMetaData directory under a given package ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -IncludePath Switch to instruct the cmdlet to include the path for the object found ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365ActiveAzureStorageConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365ActiveAzureStorageConfig ## SYNOPSIS Get active Azure Storage Account configuration ## SYNTAX ``` Get-D365ActiveAzureStorageConfig [-OutputAsPsCustomObject] [] ``` ## DESCRIPTION Get active Azure Storage Account configuration object from the configuration store ## EXAMPLES ### EXAMPLE 1 ``` Get-D365ActiveAzureStorageConfig ``` This will get the active Azure Storage configuration. ### EXAMPLE 2 ``` Get-D365ActiveAzureStorageConfig -OutputAsPsCustomObject ``` This will get the active Azure Storage configuration. The object will be output as a PsCustomObject, for you to utilize across your scripts. ## PARAMETERS ### -OutputAsPsCustomObject Instruct the cmdlet to return a PsCustomObject object ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, Container Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365ActiveBroadcastMessageConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365ActiveBroadcastMessageConfig ## SYNOPSIS Get active broadcast message configuration ## SYNTAX ``` Get-D365ActiveBroadcastMessageConfig [-OutputAsHashtable] [] ``` ## DESCRIPTION Get active broadcast message configuration from the configuration store ## EXAMPLES ### EXAMPLE 1 ``` Get-D365ActiveBroadcastMessageConfig ``` This will get the active broadcast message configuration. ## PARAMETERS ### -OutputAsHashtable Instruct the cmdlet to return a hastable object ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Servicing, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Add-D365BroadcastMessageConfig]() [Clear-D365ActiveBroadcastMessageConfig]() [Get-D365BroadcastMessageConfig]() [Remove-D365BroadcastMessageConfig]() [Send-D365BroadcastMessage]() [Set-D365ActiveBroadcastMessageConfig]() ================================================ FILE: docs/Get-D365AzureDevOpsNuget.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365AzureDevOpsNuget ## SYNOPSIS Get Azure DevOps nugets ## SYNTAX ``` Get-D365AzureDevOpsNuget [-Url] [-FeedName] [-PeronalAccessToken] [[-Name] ] [-Latest] [] ``` ## DESCRIPTION Get Azure DevOps nugets from a feed, to list all available details ## EXAMPLES ### EXAMPLE 1 ``` Get-D365AzureDevOpsNuget -Uri "https://dev.azure.com/Contoso/Financials" -FeedName "AASBuild365" -PeronalAccessToken "m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny" ``` This will list all packages / nugets from the Azure DevOps feed. Foreach packacge, it will list all available versions. The http request will be going to the Uri "https://dev.azure.com/Contoso/Financials". The feed is identified by the FeedName "AASBuild365". The request will authenticate with the PeronalAccessToken "m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny" ### EXAMPLE 2 ``` Get-D365AzureDevOpsNuget -Uri "https://dev.azure.com/Contoso/Financials" -FeedName "AASBuild365" -PeronalAccessToken "m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny" -Latest ``` This will list all packages / nugets from the Azure DevOps feed. Foreach packacge, it will only list the latest version (highest). The http request will be going to the Uri "https://dev.azure.com/Contoso/Financials". The feed is identified by the FeedName "AASBuild365". The request will authenticate with the PeronalAccessToken "m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny" The cmdlet will only output the latest version by the Latest switch. ### EXAMPLE 3 ``` $currentNugets = Get-D365AzureDevOpsNuget -Uri "https://dev.azure.com/Contoso/Financials" -FeedName "AASBuild365" -PeronalAccessToken "m9o7jfuch0huJ0YP2W46tTB90TQrMv0rcoZNaueBs3TLy68vF4Ny" -Latest ``` PS C:\\\> foreach ($item in $currentNugets) { PS C:\\\> $lcsNugets = Get-D365LcsAssetFile -FileType NuGetPackage -AssetFilename "$($item.Name)*" PS C:\\\> foreach ($itemInner in $lcsNugets) { PS C:\\\> if ($itemInner.FileName -Match "\d+\.\d+\.\d+\.\d+") { PS C:\\\> if ($(\[Version\]$Matches\[0\]) -gt \[Version\]$item.Version) { PS C:\\\> $itemInner PS C:\\\> } PS C:\\\> } PS C:\\\> } PS C:\\\> } This will fetch all latest nugets from the Azure DevOps artifacts feed (nuget). For each nuget found, it will fetch matching nugets from the LCS Asset Library and return those that have a higher version. This can be used to automatically download and push the latest nuget from LCS to Azure DevOps. Needs to be put into work with Invoke-D365AzureDevOpsNugetPush ## PARAMETERS ### -Url The Azure DevOps url that you want to work against 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. ```yaml Type: String Parameter Sets: (All) Aliases: Uri Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -FeedName Name of the feed that you want to work against The feed name is found under the Artifacts area in Azure DevOps ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -PeronalAccessToken The Personal Access Token that you need to provide for the cmdlet to be able to communicate with the Azure DevOps REST services The Personal Access Token is configured via the Azure DevOps portal, on your own account ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Name Name of the package / nuget that you are searching for Supports wildcard searching e.g. "*platform*" will output all packages / nugets that matches the search pattern Default value is "*" which will search for all packages / nugets ```yaml Type: String Parameter Sets: (All) Aliases: PackageName Required: False Position: 4 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -Latest Instruct the cmdlet to only fetch the latest package / nuget based on the version (highest) ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365AzureStorageConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365AzureStorageConfig ## SYNOPSIS Get Azure Storage Account configs ## SYNTAX ``` Get-D365AzureStorageConfig [[-Name] ] [-OutputAsHashtable] [] ``` ## DESCRIPTION Get all Azure Storage Account configuration objects from the configuration store ## EXAMPLES ### EXAMPLE 1 ``` Get-D365AzureStorageConfig ``` This will show all Azure Storage Account configs ### EXAMPLE 2 ``` Get-D365AzureStorageConfig -OutputAsHashtable ``` This will show all Azure Storage Account configs. Every object will be output as a hashtable, for you to utilize as parameters for other cmdlets. ## PARAMETERS ### -Name The name of the Azure Storage Account you are looking for Default value is "*" to display all Azure Storage Account configs ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputAsHashtable Instruct the cmdlet to return a hastable object ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, Container Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365AzureStorageFile.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365AzureStorageFile ## SYNOPSIS Get file information from Azure Storage ## SYNTAX ### Default (Default) ``` Get-D365AzureStorageFile [-AccountId ] [-AccessToken ] [-SAS ] [-Container ] [-Name ] [] ``` ### Latest ``` Get-D365AzureStorageFile [-AccountId ] [-AccessToken ] [-SAS ] [-Container ] [-Latest] [] ``` ## DESCRIPTION Get information for files from an Azure Storage Account ## EXAMPLES ### EXAMPLE 1 ``` Get-D365AzureStorageFile -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Container "backupfiles" ``` This will get information for all files in the blob container "backupfiles". It will use the AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" to gain access. ### EXAMPLE 2 ``` Get-D365AzureStorageFile -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Container "backupfiles" -Latest ``` This will get information for the latest (newest) file from the blob container "backupfiles". It will use the AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" to gain access to the container. ### EXAMPLE 3 ``` Get-D365AzureStorageFile -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Container "backupfiles" -Name "*UAT*" ``` This will get information for all files in the blob container "backupfiles" that fits the "*UAT*" search value. It will use the AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" to gain access to the container. ### EXAMPLE 4 ``` Get-D365AzureStorageFile -AccountId "miscfiles" -SAS "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" -Container "backupfiles" -Latest ``` This will get information for the latest (newest) file from the blob container "backupfiles". It will use the SAS key "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" to gain access to the container. ## PARAMETERS ### -AccountId Storage Account Name / Storage Account Id where file information should be retrieved from ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:AzureStorageAccountId Accept pipeline input: False Accept wildcard characters: False ``` ### -AccessToken The token that has the needed permissions for the search action ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:AzureStorageAccessToken Accept pipeline input: False Accept wildcard characters: False ``` ### -SAS The SAS key for the storage account or blob container ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:AzureStorageSAS Accept pipeline input: False Accept wildcard characters: False ``` ### -Container Name of the blob container inside the storage account where file information should be retrieved from ```yaml Type: String Parameter Sets: (All) Aliases: Blobname, Blob Required: False Position: Named Default value: $Script:AzureStorageContainer Accept pipeline input: False Accept wildcard characters: False ``` ### -Name Name of the files information should be retrieved for Accepts wildcards for searching. E.g. -Name "Application*Adaptor" Default value is "*" which will search for all files ```yaml Type: String Parameter Sets: Default Aliases: FileName Required: False Position: Named Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -Latest Instruct the cmdlet to only fetch the information of the latest file from the Azure Storage Account ```yaml Type: SwitchParameter Parameter Sets: Latest Aliases: GetLatest Required: True Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Azure, Azure Storage, Token, Blob, File, Container Author: Mötz Jensen (@Splaxi) Author: Florian Hopfner (@FH-Inway) ## RELATED LINKS ================================================ FILE: docs/Get-D365AzureStorageUrl.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365AzureStorageUrl ## SYNOPSIS Get a blob Url from Azure Storage account ## SYNTAX ``` Get-D365AzureStorageUrl [[-AccountId] ] [[-SAS] ] [[-Container] ] [-OutputAsHashtable] [] ``` ## DESCRIPTION Get a valid blob container url from an Azure Storage Account ## EXAMPLES ### EXAMPLE 1 ``` Get-D365AzureStorageUrl -AccountId "miscfiles" -SAS "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" -Container "backupfiles" ``` This will generate a valid Url for the blob container in the Azure Storage Account. It will use the AccountId "miscfiles" as the name of the storage account. It will use the SAS key "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" to add the SAS token/key to the Url. It will use the Container "backupfiles" as the container name in the Url. ### EXAMPLE 2 ``` Get-D365AzureStorageUrl ``` This will generate a valid Url for the blob container in the Azure Storage Account. It will use the default values that are configured using the Set-D365ActiveAzureStorageConfig cmdlet and view using the Get-D365ActiveAzureStorageConfig cmdlet. ### EXAMPLE 3 ``` Get-D365AzureStorageUrl -OutputAsHashtable ``` This will generate a valid Url for the blob container in the Azure Storage Account. It will use the default values that are configured using the Set-D365ActiveAzureStorageConfig cmdlet and view using the Get-D365ActiveAzureStorageConfig cmdlet. The output object will be a Hashtable, which you can use as a parameter for other cmdlets. ### EXAMPLE 4 ``` $DestinationParms = Get-D365AzureStorageUrl -OutputAsHashtable ``` PS C:\\\> $BlobFileDetails = Get-D365LcsDatabaseBackups -Latest | Invoke-D365AzCopyTransfer @DestinationParms PS C:\\\> $BlobFileDetails | Invoke-D365AzCopyTransfer -DestinationUri "C:\Temp" -DeleteOnTransferComplete This will transfer the lastest backup file from LCS Asset Library to your local "C:\Temp". It will get a destination Url, for it to transfer the backup file between the LCS storage account and your own. The newly transfered file, that lives in your own storage account, will then be downloaded to your local "c:\Temp". After the file has been downloaded to your local "C:\Temp", it will be deleted from your own storage account. ## PARAMETERS ### -AccountId Storage Account Name / Storage Account Id you want to work against ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:AzureStorageAccountId Accept pipeline input: False Accept wildcard characters: False ``` ### -SAS The SAS key that you have created for the storage account or blob container ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:AzureStorageSAS Accept pipeline input: False Accept wildcard characters: False ``` ### -Container Name of the blob container inside the storage account you want to work against ```yaml Type: String Parameter Sets: (All) Aliases: Blobname, Blob Required: False Position: 3 Default value: $Script:AzureStorageContainer Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputAsHashtable Instruct the cmdlet to return a hastable object ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Azure, Azure Storage, Token, Blob, File, Container, LCS, Asset, Bacpac, Backup Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365BacpacSqlOptions.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365BacpacSqlOptions ## SYNOPSIS Get the SQL Server options from the bacpac model.xml file ## SYNTAX ``` Get-D365BacpacSqlOptions [[-Path] ] [] ``` ## DESCRIPTION Extract the SQL Server options that are listed inside the model.xml file originating from a bacpac file ## EXAMPLES ### EXAMPLE 1 ``` Get-D365BacpacSqlOptions -Path "c:\temp\d365fo.tools\bacpac.model.xml" ``` This will display all the SQL Server options configured in the bacpac model file. ### EXAMPLE 2 ``` Export-D365BacpacModelFile -Path "c:\Temp\AxDB.bacpac" | Get-D365BacpacSqlOptions ``` This will display all the SQL Server options configured in the bacpac file. First it will export the model.xml from the "c:\Temp\AxDB.bacpac" file, using the Export-D365BacpacModelFile function. The output from Export-D365BacpacModelFile will be piped into the Get-D365BacpacSqlOptions function. ## PARAMETERS ### -Path Path to the extracted model.xml file that you want to work against ```yaml Type: String Parameter Sets: (All) Aliases: File, ModelFile Required: False Position: 1 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Bacpac, Servicing, Data, SqlPackage, Sql Server Options, Collation Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365BacpacTable.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365BacpacTable ## SYNOPSIS Get tables from the bacpac file ## SYNTAX ### Default (Default) ``` Get-D365BacpacTable -Path [-Table ] [-Top ] [] ``` ### SortSizeAsc ``` Get-D365BacpacTable -Path [-Table ] [-Top ] [-SortSizeAsc] [] ``` ### SortSizeDesc ``` Get-D365BacpacTable -Path [-Table ] [-Top ] [-SortSizeDesc] [] ``` ## DESCRIPTION Get tables and their metadata from the bacpac file 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 ## EXAMPLES ### EXAMPLE 1 ``` Get-D365BacpacTable -Path "c:\Temp\AxDB.bacpac" ``` This will return all tables from inside the bacpac file. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "*" as the Table parameter, to output all tables. It uses the default value "\[int\]::max" as the Top parameter, to output all tables. It uses the default sort, which is by name acsending. A result set example: Name OriginalSize CompressedSize BulkFiles ---- ------------ -------------- --------- ax.DBVERSION 62 B 52 B 1 crt.RETAILUPGRADEHISTORY 13,49 MB 13,41 MB 3 dbo.__AOSMESSAGEREGISTRATION 1,80 KB 540 B 2 dbo.__AOSSTARTUPVERSION 4 B 6 B 1 dbo.ACCOUNTINGDISTRIBUTION 48,60 MB 4,50 MB 95 dbo.ACCOUNTINGEVENT 11,16 MB 1,51 MB 128 dbo.AGREEMENTPARAMETERS_RU 366 B 113 B 1 dbo.AIFSQLCDCENABLEDTABLES 13,63 KB 2,19 KB 1 dbo.AIFSQLCHANGETRACKINGENABLEDTABLES 9,89 KB 1,42 KB 1 dbo.AIFSQLCTTRIGGERS 44,75 KB 6,29 KB 1 ### EXAMPLE 2 ``` Get-D365BacpacTable -Path "c:\Temp\AxDB.bacpac" -SortSizeAsc ``` This will return all tables from inside the bacpac file, sorted by the original size, ascending. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "*" as the Table parameter, to output all tables. It uses the default value "\[int\]::max" as the Top parameter, to output all tables. It uses the SortSizeAsc parameter, which is by original size acsending. A result set example: Name OriginalSize CompressedSize BulkFiles ---- ------------ -------------- --------- dbo.__AOSSTARTUPVERSION 4 B 6 B 1 dbo.SYSSORTORDER 20 B 20 B 1 dbo.SECURITYDATABASESETTINGS 20 B 12 B 1 dbo.SYSPOLICYSEQUENCEGROUP 24 B 10 B 1 dbo.SYSFILESTOREPARAMETERS 26 B 10 B 1 dbo.SYSHELPCPSSETUP 28 B 15 B 1 dbo.DATABASELOGPARAMETERS 28 B 10 B 1 dbo.FEATUREMANAGEMENTPARAMETERS 28 B 10 B 1 dbo.AIFSQLCTVERSION 28 B 24 B 1 dbo.SYSHELPSETUP 28 B 15 B 1 ### EXAMPLE 3 ``` Get-D365BacpacTable -Path "c:\Temp\AxDB.bacpac" -SortSizeDesc ``` This will return all tables from inside the bacpac file, sorted by the original size, descending. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "*" as the Table parameter, to output all tables. It uses the default value "\[int\]::max" as the Top parameter, to output all tables. It uses the SortSizeDesc parameter, which is by original size descending. A result set example: Name OriginalSize CompressedSize BulkFiles ---- ------------ -------------- --------- dbo.TSTIMESHEETLINESTAGING 35,31 GB 2,44 GB 9077 dbo.RESROLLUP 13,30 GB 367,19 MB 3450 dbo.PROJECTSTAGING 11,31 GB 508,70 MB 2929 dbo.TSTIMESHEETTABLESTAGING 5,93 GB 246,65 MB 1564 dbo.BATCHHISTORY 5,80 GB 234,99 MB 1529 dbo.HCMPOSITIONHIERARCHYSTAGING 5,16 GB 222,18 MB 1358 dbo.ERLCSFILEASSETTABLE 3,15 GB 217,68 MB 302 dbo.EVENTINBOX 2,92 GB 105,63 MB 747 dbo.HCMPOSITIONV2STAGING 2,79 GB 200,27 MB 755 dbo.HCMEMPLOYEESTAGING 2,49 GB 218,69 MB 677 ### EXAMPLE 4 ``` Get-D365BacpacTable -Path "c:\Temp\AxDB.bacpac" -SortSizeDesc -Top 5 ``` This will return all tables from inside the bacpac file, sorted by the original size, descending. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "*" as the Table parameter, to output all tables. It uses the value 5 as the Top parameter, to output only 5 tables, based on the sorting selected. It uses the SortSizeDesc parameter, which is by original size descending. A result set example: Name OriginalSize CompressedSize BulkFiles ---- ------------ -------------- --------- dbo.TSTIMESHEETLINESTAGING 35,31 GB 2,44 GB 9077 dbo.RESROLLUP 13,30 GB 367,19 MB 3450 dbo.PROJECTSTAGING 11,31 GB 508,70 MB 2929 dbo.TSTIMESHEETTABLESTAGING 5,93 GB 246,65 MB 1564 dbo.BATCHHISTORY 5,80 GB 234,99 MB 1529 ### EXAMPLE 5 ``` Get-D365BacpacTable -Path "c:\Temp\AxDB.bacpac" -Table "Sales*" ``` This will return all tables which matches the "Sales*" wildcard search from inside the bacpac file. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "Sales*" as the Table parameter, to output all tables that matches the wildcard pattern. It uses the default value "\[int\]::max" as the Top parameter, to output all tables. It uses the default sort, which is by name acsending. A result set example: Name OriginalSize CompressedSize BulkFiles ---- ------------ -------------- --------- dbo.SALESPARAMETERS 4,29 KB 310 B 1 dbo.SALESPARMUPDATE 273,48 KB 24,21 KB 1 dbo.SALESQUOTATIONTOLINEPARAMETERS 4,18 KB 596 B 1 dbo.SALESSUMMARYPARAMETERS 2,95 KB 425 B 1 dbo.SALESTABLE 1,20 KB 313 B 1 dbo.SALESTABLE_W 224 B 60 B 1 dbo.SALESTABLE2LINEPARAMETERS 4,46 KB 637 B 1 ### EXAMPLE 6 ``` Get-D365BacpacTable -Path "c:\Temp\AxDB.bacpac" -Table "Sales*","CUSTINVOICE*" ``` This will return all tables which matches the "Sales*" and "CUSTINVOICE*" wildcard searches from inside the bacpac file. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "Sales*" and "CUSTINVOICE*" as the Table parameter, to output all tables that matches the wildcard pattern. It uses the default value "\[int\]::max" as the Top parameter, to output all tables. It uses the default sort, which is by name acsending. A result set example: Name OriginalSize CompressedSize BulkFiles ---- ------------ -------------- --------- dbo.CUSTINVOICEJOUR 2,01 MB 118,87 KB 1 dbo.CUSTINVOICELINE 14,64 MB 975,30 KB 4 dbo.CUSTINVOICELINEINTERPROJ 6,58 MB 477,97 KB 2 dbo.CUSTINVOICETABLE 1,06 MB 56,56 KB 1 dbo.CUSTINVOICETRANS 32,34 MB 1,51 MB 54 dbo.SALESPARAMETERS 4,29 KB 310 B 1 dbo.SALESPARMUPDATE 273,48 KB 24,21 KB 1 dbo.SALESQUOTATIONTOLINEPARAMETERS 4,18 KB 596 B 1 dbo.SALESSUMMARYPARAMETERS 2,95 KB 425 B 1 dbo.SALESTABLE 1,20 KB 313 B 1 dbo.SALESTABLE_W 224 B 60 B 1 dbo.SALESTABLE2LINEPARAMETERS 4,46 KB 637 B 1 ### EXAMPLE 7 ``` Get-D365BacpacTable -Path "c:\Temp\AxDB.bacpac" -Table "SalesTable","CustTable" ``` This will return the tables "dbo.SalesTable" and "dbo.CustTable" from inside the bacpac file. It uses "c:\Temp\AxDB.bacpac" as the Path for the bacpac file. It uses the default value "SalesTable" and "CustTable" as the Table parameter, to output the tables that matches the names. It uses the default value "\[int\]::max" as the Top parameter, to output all tables. It uses the default sort, which is by name acsending. A result set example: Name OriginalSize CompressedSize BulkFiles ---- ------------ -------------- --------- dbo.CUSTTABLE 154,91 KB 8,26 KB 1 dbo.SALESTABLE 1,20 KB 313 B 1 ## PARAMETERS ### -Path Path to the bacpac file that you want to work against It can also be a zip file ```yaml Type: String Parameter Sets: (All) Aliases: BacpacFile, File Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Table Name of the table that you want to delete the data for Supports an array of table names If a schema name isn't supplied as part of the table name, the cmdlet will prefix it with "dbo." Supports wildcard searching e.g. "Sales*" will locate all "dbo.Sales*" tables in the bacpac file ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: Named Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -Top Instruct the cmdlet with how many tables you want returned Default is \[int\]::max, which translates into all tables present inside the bapcac file ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: 2147483647 Accept pipeline input: False Accept wildcard characters: False ``` ### -SortSizeAsc Instruct the cmdlet to sort the output by size (original) ascending ```yaml Type: SwitchParameter Parameter Sets: SortSizeAsc Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -SortSizeDesc Instruct the cmdlet to sort the output by size (original) descending ```yaml Type: SwitchParameter Parameter Sets: SortSizeDesc Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Bacpac, Servicing, Data, SqlPackage, Table, Size, Troubleshooting Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365BroadcastMessage.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365BroadcastMessage ## SYNOPSIS Get broadcast message from the D365FO environment ## SYNTAX ``` Get-D365BroadcastMessage [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [-ExcludeExpired] [] ``` ## DESCRIPTION Get broadcast message from the D365FO environment by looking into the database table ## EXAMPLES ### EXAMPLE 1 ``` Get-D365BroadcastMessage ``` This will display all the broadcast message records from the SysBroadcastMessage table. ### EXAMPLE 2 ``` Get-D365BroadcastMessage -ExcludeExpired ``` This will display all active the broadcast message records from the SysBroadcastMessage table. ## PARAMETERS ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -ExcludeExpired Exclude all the records that has already expired ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Broadcast, Message, SysBroadcastMessage, Servicing, Message, Users, Environment Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365BroadcastMessageConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365BroadcastMessageConfig ## SYNOPSIS Get broadcast message configs ## SYNTAX ``` Get-D365BroadcastMessageConfig [[-Name] ] [-OutputAsHashtable] [] ``` ## DESCRIPTION Get all broadcast message configuration objects from the configuration store ## EXAMPLES ### EXAMPLE 1 ``` Get-D365BroadcastMessageConfig ``` This will display all broadcast message configurations on the machine. ### EXAMPLE 2 ``` Get-D365BroadcastMessageConfig -OutputAsHashtable ``` This will display all broadcast message configurations on the machine. Every object will be output as a hashtable, for you to utilize as parameters for other cmdlets. ### EXAMPLE 3 ``` Get-D365BroadcastMessageConfig -Name "UAT" ``` This will display the broadcast message configuration that is saved with the name "UAT" on the machine. ## PARAMETERS ### -Name The name of the broadcast message configuration you are looking for Default value is "*" to display all broadcast message configs ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputAsHashtable Instruct the cmdlet to return a hastable object ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### PSCustomObject ## NOTES Tags: Servicing, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Add-D365BroadcastMessageConfig]() [Clear-D365ActiveBroadcastMessageConfig]() [Get-D365ActiveBroadcastMessageConfig]() [Remove-D365BroadcastMessageConfig]() [Send-D365BroadcastMessage]() [Set-D365ActiveBroadcastMessageConfig]() ================================================ FILE: docs/Get-D365ClickOnceTrustPrompt.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365ClickOnceTrustPrompt ## SYNOPSIS Get the ClickOnce configuration ## SYNTAX ``` Get-D365ClickOnceTrustPrompt [] ``` ## DESCRIPTION Creates the needed registry keys and values for ClickOnce to work on the machine ## EXAMPLES ### EXAMPLE 1 ``` Get-D365ClickOnceTrustPrompt ``` This will get the current ClickOnce configuration ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: ClickOnce, Registry, TrustPrompt Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365CompilerResult.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365CompilerResult ## SYNOPSIS Get the compiler outputs presented ## SYNTAX ``` Get-D365CompilerResult [-Path] [-ErrorsOnly] [-OutputTotals] [-OutputAsObjects] [] ``` ## DESCRIPTION Get the compiler outputs presented in a structured manner on the screen It could be a Visual Studio compiler log or it could be a Invoke-D365ModuleCompile log you want analyzed ## EXAMPLES ### EXAMPLE 1 ``` Get-D365CompilerResult -Path "c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log" ``` This will analyze the compiler log file for warning and errors. A result set example: File Warnings Errors ---- -------- ------ c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log 2 1 ### EXAMPLE 2 ``` Get-D365CompilerResult -Path "c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log" -ErrorsOnly ``` This will analyze the compiler log file for warning and errors, but only output if it has errors. A result set example: File Warnings Errors ---- -------- ------ c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log 2 1 ### EXAMPLE 3 ``` Get-D365CompilerResult -Path "c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log" -ErrorsOnly -OutputAsObjects ``` This will analyze the compiler log file for warning and errors, but only output if it has errors. The output will be PSObjects, which can be assigned to a variable and used for futher analysis. A result set example: File Warnings Errors ---- -------- ------ c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log 2 1 ### EXAMPLE 4 ``` Get-D365Module -Name *Custom* | Invoke-D365ModuleCompile | Get-D365CompilerResult -OutputTotals ``` This will find all modules with Custom in their name. It will pass thoses modules into the Invoke-D365ModuleCompile, which will compile them. It will pass the paths to each compile output log to Get-D365CompilerResult, which will analyze them for warning and errors. It will output the total number of warning and errors found. File Warnings Errors ---- -------- ------ c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log 2 1 Total Errors: 1 Total Warnings: 2 ## PARAMETERS ### -Path Path to the compiler log file that you want to work against A BuildModelResult.log or a Dynamics.AX.*.xppc.log file will both work ```yaml Type: String Parameter Sets: (All) Aliases: LogFile Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -ErrorsOnly Instructs the cmdlet to only output compile results where there was errors detected ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputTotals Instructs the cmdlet to output the total errors and warnings after the analysis ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputAsObjects Instructs the cmdlet to output the objects instead of formatting them 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 ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### [PsCustomObject] ## NOTES Tags: Compiler, Build, Errors, Warnings, Tasks Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Vilmos Kintera" (twitter: @DAXRunBase) All credits goes to him for showing how to extract these information His blog can be found here: https://www.daxrunbase.com/blog/ The specific blog post that we based this cmdlet on can be found here: https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/ The github repository containing the original scrips can be found here: https://github.com/DAXRunBase/PowerShell-and-Azure ## RELATED LINKS ================================================ FILE: docs/Get-D365Database.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365Database ## SYNOPSIS Get databases from the server ## SYNTAX ``` Get-D365Database [[-Name] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [] ``` ## DESCRIPTION Get the names of databases on either SQL Server or in Azure SQL Database instance ## EXAMPLES ### EXAMPLE 1 ``` Get-D365Database ``` This will show all databases on the default SQL Server / Azure SQL Database instance. ### EXAMPLE 2 ``` Get-D365Database -Name AXDB_ORIGINAL ``` This will show if the AXDB_ORIGINAL database exists on the default SQL Server / Azure SQL Database instance. ## PARAMETERS ### -Name Name of the database that you are looking for Default value is "*" which will show all databases ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### [PsCustomObject] ## NOTES Tags: Database, DB, Servicing Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365DatabaseAccess.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365DatabaseAccess ## SYNOPSIS Shows the Database Access information for the D365 Environment ## SYNTAX ``` Get-D365DatabaseAccess [] ``` ## DESCRIPTION Gets all database information from the D365 environment ## EXAMPLES ### EXAMPLE 1 ``` Get-D365DatabaseAccess ``` This will get all relevant details, including connection details, for the database configured for the environment ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Database, Connection, Sql, SqlUser, SqlPwd Author: Rasmus Andersen (@ITRasmus) The cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations. The call to the dll file gets all relevant connections details for the database server. ## RELATED LINKS ================================================ FILE: docs/Get-D365DecryptedWebConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365DecryptedWebConfig ## SYNOPSIS Decrypts the AOS config file ## SYNTAX ``` Get-D365DecryptedWebConfig [[-OutputPath] ] [[-AosServiceWebRootPath] ] ``` ## DESCRIPTION Function used for decrypting the config file used by the D365 Finance & Operations AOS service ## EXAMPLES ### EXAMPLE 1 ``` Get-D365DecryptedWebConfig ``` This will get the config file from the instance, decrypt it and save it. IT will save the decrypted web.config file in the default location: "c:\temp\d365fo.tools\WebConfigDecrypted". A result set example: Filename LastModified File -------- ------------ ---- web.config 7/1/2021 9:01:31 PM C:\temp\d365fo.tools\WebConfigDecrypted\web.config ### EXAMPLE 2 ``` Get-D365DecryptedWebConfig -OutputPath "c:\temp\d365fo.tools" ``` This will get the config file from the instance, decrypt it and save it to "c:\temp\d365fo.tools" A result set example: Filename LastModified File -------- ------------ ---- web.config 7/1/2021 9:07:36 PM C:\temp\d365fo.tools\web.config ## PARAMETERS ### -OutputPath Place where the decrypted files should be placed Default value is: "c:\temp\d365fo.tools\WebConfigDecrypted" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: C:\temp\d365fo.tools\WebConfigDecrypted Accept pipeline input: False Accept wildcard characters: False ``` ### -AosServiceWebRootPath Location of the D365 webroot folder ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:AOSPath Accept pipeline input: False Accept wildcard characters: False ``` ## INPUTS ## OUTPUTS ## NOTES Tags: Configuration, Service Account, Sql, SqlUser, SqlPwd, WebConfig, Web.Config, Decryption Author : Rasmus Andersen (@ITRasmus) Author : Mötz Jensen (@splaxi) Used for getting the Password for the database and other service accounts used in environment ## RELATED LINKS ================================================ FILE: docs/Get-D365DefaultModelForNewProjects.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365DefaultModelForNewProjects ## SYNOPSIS Get the default model used creating new projects in Visual Studio ## SYNTAX ``` Get-D365DefaultModelForNewProjects [] ``` ## 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 ## EXAMPLES ### EXAMPLE 1 ``` Get-D365DefaultModelForNewProjects ``` This will display the current default module registered in the "DynamicsDevConfig.xml" file. Located in Documents\Visual Studio Dynamics 365\ or in Documents\Visual Studio 2015\Settings\ depending on the version. ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tag: Model, Models, Development, Default Model, Module, Project Author: Mötz Jensen (@Splaxi) The work for this cmdlet / function was inspired by Robin Kretzschmar (@DarkSmile92) blog post about changing the default model. The direct link for his blog post is: https://robscode.onl/d365-set-default-model-for-new-projects/ His main blog can found here: https://robscode.onl/ ## RELATED LINKS ================================================ FILE: docs/Get-D365DotNetClass.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365DotNetClass ## SYNOPSIS Get a .NET class from the Dynamics 365 for Finance and Operations installation ## SYNTAX ``` Get-D365DotNetClass [[-Name] ] [[-Assembly] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Get a .NET class from an assembly file (dll) from the package directory ## EXAMPLES ### EXAMPLE 1 ``` Get-D365DotNetClass -Name "ERText*" ``` Will search across all assembly files (*.dll) that are located in the default package directory after any class that fits the search "ERText*" ### EXAMPLE 2 ``` Get-D365DotNetClass -Name "ERText*" -Assembly "*LocalizationFrameworkForAx.dll*" ``` Will search across all assembly files (*.dll) that are fits the search "*LocalizationFrameworkForAx.dll*", that are located in the default package directory, after any class that fits the search "ERText*" ### EXAMPLE 3 ``` Get-D365DotNetClass -Name "ERText*" | Export-Csv -Path c:\temp\results.txt -Delimiter ";" ``` Will search across all assembly files (*.dll) that are located in the default package directory after any class that fits the search "ERText*" The output is saved to a file to make it easier to search inside the result set ## PARAMETERS ### -Name Name of the .NET class that you are looking for Accepts wildcards for searching. E.g. -Name "ER*Excel*" Default value is "*" which will search for all classes ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -Assembly Name of the assembly file that you want to search for the .NET class Accepts wildcards for searching. E.g. -Name "*AX*Framework*.dll" Default value is "*.dll" which will search for assembly files ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: *.dll Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed packages Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: .Net, DotNet, Class, Development Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. ## RELATED LINKS ================================================ FILE: docs/Get-D365DotNetMethod.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365DotNetMethod ## SYNOPSIS Get a .NET method from the Dynamics 365 for Finance and Operations installation ## SYNTAX ``` Get-D365DotNetMethod [-Assembly] [[-Name] ] [[-TypeName] ] [] ``` ## DESCRIPTION Get a .NET method from an assembly file (dll) from the package directory ## EXAMPLES ### EXAMPLE 1 ``` Get-D365DotNetMethod -Assembly "C:\AOSService\PackagesLocalDirectory\ElectronicReporting\bin\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll" ``` Will get all methods, across all classes, from the assembly file ### EXAMPLE 2 ``` Get-D365DotNetMethod -Assembly "C:\AOSService\PackagesLocalDirectory\ElectronicReporting\bin\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll" -TypeName "ERTextFormatExcelFileComponent" ``` Will get all methods, from the "ERTextFormatExcelFileComponent" class, from the assembly file ### EXAMPLE 3 ``` Get-D365DotNetMethod -Assembly "C:\AOSService\PackagesLocalDirectory\ElectronicReporting\bin\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll" -TypeName "ERTextFormatExcelFileComponent" -Name "*parm*" ``` Will get all methods that fits the search "*parm*", from the "ERTextFormatExcelFileComponent" class, from the assembly file ### EXAMPLE 4 ``` Get-D365DotNetClass -Name "ERTextFormatExcelFileComponent" -Assembly "*LocalizationFrameworkForAx.dll*" | Get-D365DotNetMethod ``` Will get all methods, from the "ERTextFormatExcelFileComponent" class, from any assembly file that fits the search "*LocalizationFrameworkForAx.dll*" ## PARAMETERS ### -Assembly Name of the assembly file that you want to search for the .NET method Provide the full path for the assembly file you want to work against ```yaml Type: String Parameter Sets: (All) Aliases: File Required: True Position: 2 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Name Name of the .NET method that you are looking for Accepts wildcards for searching. E.g. -Name "parmER*Excel*" Default value is "*" which will search for all methods ```yaml Type: String Parameter Sets: (All) Aliases: MethodName Required: False Position: 3 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -TypeName Name of the .NET class that you want to work against Accepts wildcards for searching. E.g. -Name "*ER*Excel*" Default value is "*" which will work against all classes ```yaml Type: String Parameter Sets: (All) Aliases: ClassName Required: False Position: 4 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: .Net, DotNet, Class, Method, Methods, Development Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. ## RELATED LINKS ================================================ FILE: docs/Get-D365Environment.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365Environment ## SYNOPSIS Cmdlet to get the current status for the different services in a Dynamics 365 Finance & Operations environment ## SYNTAX ### Default (Default) ``` Get-D365Environment [[-ComputerName] ] [-All] [-OnlyStartTypeAutomatic] [-OutputServiceDetailsOnly] [] ``` ### Specific ``` Get-D365Environment [[-ComputerName] ] [-Aos] [-Batch] [-FinancialReporter] [-DMF] [-OnlyStartTypeAutomatic] [-OutputServiceDetailsOnly] [] ``` ## DESCRIPTION List status for all relevant services that is running in a D365FO environment ## EXAMPLES ### EXAMPLE 1 ``` Get-D365Environment ``` Will query all D365FO service on the machine. ### EXAMPLE 2 ``` Get-D365Environment -All ``` Will query all D365FO service on the machine. ### EXAMPLE 3 ``` Get-D365Environment -OnlyStartTypeAutomatic ``` Will query all D365FO service on the machine. It will filter out all services that are either configured as manual or disabled. ### EXAMPLE 4 ``` Get-D365Environment -ComputerName "TEST-SB-AOS1","TEST-SB-AOS2","TEST-SB-BI1" -All ``` Will query all D365FO service on the different machines. ### EXAMPLE 5 ``` Get-D365Environment -Aos -Batch ``` Will query the Aos & Batch services on the machine. ### EXAMPLE 6 ``` Get-D365Environment -FinancialReporter -DMF ``` Will query the FinancialReporter & DMF services on the machine. ### EXAMPLE 7 ``` Get-D365Environment -OutputServiceDetailsOnly ``` Will query all D365FO service on the machine. Will omit the servername from the output. ### EXAMPLE 8 ``` Get-D365Environment -FinancialReporter | Set-Service -StartupType Manual ``` This will configure the Financial Reporter services to be start type manual. ## PARAMETERS ### -ComputerName An array of computers that you want to query for the services status on. ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: @($env:computername) Accept pipeline input: False Accept wildcard characters: False ``` ### -All Set when you want to query all relevant services Includes: Aos Batch Financial Reporter DMF ```yaml Type: SwitchParameter Parameter Sets: Default Aliases: Required: False Position: Named Default value: True Accept pipeline input: False Accept wildcard characters: False ``` ### -Aos Instruct the cmdlet to query the AOS (IIS) service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Batch Instruct the cmdlet query the batch service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -FinancialReporter Instruct the cmdlet query the financial reporter (Management Reporter 2012) ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -DMF Instruct the cmdlet query the DMF service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OnlyStartTypeAutomatic Instruct the cmdlet to filter out services that are set to manual start or disabled ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputServiceDetailsOnly Instruct the cmdlet to exclude the server name from the output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Environment, Service, Services, Aos, Batch, Servicing Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365EnvironmentSettings.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365EnvironmentSettings ## SYNOPSIS Get the D365FO environment settings ## SYNTAX ``` Get-D365EnvironmentSettings [] ``` ## DESCRIPTION Gets all settings the Dynamics 365 for Finance & Operations environment uses. ## EXAMPLES ### EXAMPLE 1 ``` Get-D365EnvironmentSettings ``` This will get all details available for the environment ### EXAMPLE 2 ``` Get-D365EnvironmentSettings | Format-Custom -Property * ``` This will get all details available for the environment and format it to show all details in a long custom object. ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Environment, Configuration, WebConfig, Web.Config, Decryption Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) The cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations. The call to the dll file gets all relevant details for the installation. ## RELATED LINKS ================================================ FILE: docs/Get-D365EventTraceProvider.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365EventTraceProvider ## SYNOPSIS Get D365FO Event Trace Provider ## SYNTAX ``` Get-D365EventTraceProvider [[-Name] ] [] ``` ## DESCRIPTION Get the full list of available Event Trace Providers for Dynamics 365 for Finance and Operations ## EXAMPLES ### EXAMPLE 1 ``` Get-D365EventTraceProvider ``` Will list all available Event Trace Providers on a D365FO server. It will use the default option for the "Name" parameter. ### EXAMPLE 2 ``` Get-D365EventTraceProvider -Name Tax ``` Will list all available Event Trace Providers on a D365FO server which contains the keyvword "Tax". It will use the Name parameter value "Tax" while searching for Event Trace Providers. ### EXAMPLE 3 ``` Get-D365EventTraceProvider -Name Tax,MR ``` Will list all available Event Trace Providers on a D365FO server which contains the keyvword "Tax" or "MR". It will use the Name parameter array value ("Tax","MR") while searching for Event Trace Providers. ## PARAMETERS ### -Name Name of the provider that you are looking for Default value is "*" to show all Event Trace Providers Accepts an array of names, and will automatically add wildcard searching characters for each entry ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: @("*") Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: ETL, EventTracing, EventTrace Author: Mötz Jensen (@Splaxi) This cmdlet/function was inspired by the work of Michael Stashwick (@D365Stuff) He blog is located here: https://www.d365stuff.co/ 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/ ## RELATED LINKS ================================================ FILE: docs/Get-D365ExternalIP.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365ExternalIP ## SYNOPSIS Get the external IP address ## SYNTAX ``` Get-D365ExternalIP [-SaveToClipboard] [] ``` ## DESCRIPTION Get the external IP address by calling an external webpage and interpret the result from that ## EXAMPLES ### EXAMPLE 1 ``` Get-D365ExternalIP ``` Will call the external page, interpret the output and display it as output. A result set example: IpAddress --------- 40.113.130.229 ### EXAMPLE 2 ``` Get-D365ExternalIP -SaveToClipboard ``` Will call the external page, interpret the output and display it as output. It will save/copy the IP address into the clipboard. A result set example: IpAddress --------- 40.113.130.229 ## PARAMETERS ### -SaveToClipboard Instruct the cmdlet to copy the IP address directly into the clipboard, to save you the trouble ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB, IP Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365Flight.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365Flight ## SYNOPSIS Used to get a flight ## SYNTAX ``` Get-D365Flight [[-FlightName] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [] ``` ## DESCRIPTION Provides a method for listing a flight in D365FO. ## EXAMPLES ### EXAMPLE 1 ``` Get-D365Flight ``` This will list all flights that are configured on the environment. It will show the name and the enabled status. A result set example: FlightName Enabled FlightServiceId ---------- ------- --------------- WHSWorkCancelForcedFlight 1 12719367 TAMRebateGlobalEnableFeature 1 12719367 EnablePerfInfoSimpleLoggerV2 1 12719367 EnablePerfInfoLogODataV2 1 12719367 EnablePerfInfoLogEtwRequestTableV2 1 12719367 EnablePerfInfoCursorLayerV2 1 12719367 EnablePerfInfoFormEngineLayerV2 1 12719367 EnablePerfInfoMutexWaitLayerV2 1 12719367 EnablePerfInfoSecurityLayerV2 1 12719367 EnablePerfInfoSessionLayerV2 1 12719367 EnablePerfInfoSQLLayerV2 1 12719367 EnablePerfInfoXppContainerLayerV2 1 12719367 ### EXAMPLE 2 ``` Get-D365Flight -FlightName WHSWorkCancelForcedFlight ``` This will list the flight with the specified name on the environment. It will show the name and the enabled status. A result set example: FlightName Enabled FlightServiceId ---------- ------- --------------- WHSWorkCancelForcedFlight 1 12719367 ### EXAMPLE 3 ``` Get-D365Flight -FlightName WHS* ``` This will list the flight with the specified pattern on the environment. It will filter the output to match the "WHS*" pattern. It will show the name and the enabled status. A result set example: FlightName Enabled FlightServiceId ---------- ------- --------------- WHSWorkCancelForcedFlight 1 12719367 ## PARAMETERS ### -FlightName Name of the flight that you are looking for Supports wildcards "*" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Flight, Flighting Author: Mötz Jensen (@Splaxi) At no circumstances can this cmdlet be used to enable a flight in a PROD environment. ## RELATED LINKS ================================================ FILE: docs/Get-D365IISPreload.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365IISPreload ## SYNOPSIS Gets IIS Preload status for the AOSService application pool and website. ## SYNTAX ``` Get-D365IISPreload [] ``` ## DESCRIPTION Returns the current IIS Preload configuration for the AOSService application: - Application Pool Start Mode - Idle Time-out - Website Preload Enabled - doAppInitAfterRestart (if Application Initialization is installed) ## EXAMPLES ### EXAMPLE 1 ``` Get-D365IISPreload ``` Retrieves the IIS Preload configuration for the AOSService application pool and website. ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### System.Management.Automation.PSCustomObject ### A custom object containing the following properties: ### - AppPool: Name of the application pool (AOSService) ### - StartMode: Start mode of the application pool (e.g., AlwaysRunning) ### - IdleTimeout: Idle timeout of the application pool (e.g., 00:00:00) ### - Site: Name of the website (AOSService) ### - PreloadEnabled: Indicates if preload is enabled for the website (True/False) ### - DoAppInitAfterRestart: Indicates if doAppInitAfterRestart is enabled (if Application Initialization is installed) ### - PreloadPage: The initialization page configured for preload (if any) ### - IISApplicationInitFeature: State of the IIS Application Initialization feature (Installed/Not installed) ## NOTES Author: Florian Hopfner (FH-Inway) 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) Written with GitHub Copilot GPT-4.1, mostly in agent mode. See commits for prompts. ## RELATED LINKS [Enable-D365IISPreload]() [Disable-D365IISPreload]() ================================================ FILE: docs/Get-D365InstalledHotfix.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365InstalledHotfix ## SYNOPSIS Get installed hotfix (DEPRECATED) ## SYNTAX ``` Get-D365InstalledHotfix [[-BinDir] ] [[-PackageDirectory] ] [[-Model] ] [[-Name] ] [[-KB] ] [] ``` ## 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. ## EXAMPLES ### EXAMPLE 1 ``` Get-D365InstalledHotfix ``` This will display all installed hotfixes found on this machine ### EXAMPLE 2 ``` Get-D365InstalledHotfix -Model "*retail*" ``` This will display all installed hotfixes found for all models that matches the search for "*retail*" found on this machine ### EXAMPLE 3 ``` Get-D365InstalledHotfix -Model "*retail*" -KB "*43*" ``` 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 ## PARAMETERS ### -BinDir The path to the bin directory for the environment Default path is the same as the AOS Service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the PackagesLocalDirectory Default path is the same as the AOS Service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### -Model Name of the model that you want to work against Accepts wildcards for searching. E.g. -Model "*Retail*" Default value is "*" which will search for all models ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -Name Name of the hotfix that you are looking for Accepts wildcards for searching. E.g. -Name "7045*" Default value is "*" which will search for all hotfixes ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -KB KB number of the hotfix that you are looking for Accepts wildcards for searching. E.g. -KB "4045*" Default value is "*" which will search for all KB's ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Hotfix, Servicing, Model, Models, KB, Patch, Patching, PackagesLocalDirectory Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Ievgen Miroshnikov" (twitter: @IevgenMir) All credits goes to him for showing how to extract these information His blog can be found here: https://ievgensaxblog.wordpress.com The specific blog post that we based this cmdlet on can be found here: https://ievgensaxblog.wordpress.com/2017/11/17/d365foe-get-list-of-installed-metadata-hotfixes-using-metadata-api/ ## RELATED LINKS ================================================ FILE: docs/Get-D365InstalledPackage.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365InstalledPackage ## SYNOPSIS Get installed package from Dynamics 365 Finance & Operations environment ## SYNTAX ``` Get-D365InstalledPackage [[-Name] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Get installed package from the machine running the AOS service for Dynamics 365 Finance & Operations ## EXAMPLES ### EXAMPLE 1 ``` Get-D365InstalledPackage ``` Shows the entire list of installed packages located in the default location on the machine A result set example: ApplicationFoundationFormAdaptor ApplicationPlatformFormAdaptor ApplicationSuiteFormAdaptor ApplicationWorkspacesFormAdaptor ### EXAMPLE 2 ``` Get-D365InstalledPackage -Name "Application*Adaptor" ``` Shows the list of installed packages where the name fits the search "Application*Adaptor" A result set example: ApplicationFoundationFormAdaptor ApplicationPlatformFormAdaptor ApplicationSuiteFormAdaptor ApplicationWorkspacesFormAdaptor ### EXAMPLE 3 ``` Get-D365InstalledPackage -PackageDirectory "J:\AOSService\PackagesLocalDirectory" ``` Shows the entire list of installed packages located in "J:\AOSService\PackagesLocalDirectory" on the machine A result set example: ApplicationFoundationFormAdaptor ApplicationPlatformFormAdaptor ApplicationSuiteFormAdaptor ApplicationWorkspacesFormAdaptor ## PARAMETERS ### -Name Name of the package that you are looking for Accepts wildcards for searching. E.g. -Name "Application*Adaptor" Default value is "*" which will search for all packages ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed packages Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: PackagesLocalDirectory, Servicing, Model, Models, Package, Packages Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. ## RELATED LINKS ================================================ FILE: docs/Get-D365InstalledService.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365InstalledService ## SYNOPSIS Get installed D365 services ## SYNTAX ``` Get-D365InstalledService [[-Path] ] [] ``` ## DESCRIPTION Get installed Dynamics 365 for Finance & Operations services that are installed on the machine ## EXAMPLES ### EXAMPLE 1 ``` Get-D365InstalledService ``` This will get all installed services on the machine. ## PARAMETERS ### -Path Path to the folder that contains the "InstallationRecords" folder ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:InstallationRecordsDir Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Services, Servicing, Topology Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365InstanceName.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365InstanceName ## SYNOPSIS Gets the instance name ## SYNTAX ``` Get-D365InstanceName [] ``` ## DESCRIPTION Get the instance name that is registered in the environment ## EXAMPLES ### EXAMPLE 1 ``` Get-D365InstanceName ``` This will get the service name that the environment has configured ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Instance, Servicing Author: Rasmus Andersen (@ITRasmus) The cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations. The call to the dll file gets HostedServiceName that is registered in the environment. ## RELATED LINKS ================================================ FILE: docs/Get-D365JsonService.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365JsonService ## SYNOPSIS Get Json based service ## SYNTAX ``` Get-D365JsonService [[-Name] ] [-Url] [-Tenant] [-ClientId] [-ClientSecret] [-RawOutput] [-OutputAsJson] [] ``` ## DESCRIPTION Get Json based services that are available from a Dynamics 365 Finance & Operations environment ## EXAMPLES ### EXAMPLE 1 ``` 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" ``` This will get all available service groups for the D365FO instance. It will contact the D365FO instance specified in the Url parameter: "https://usnconeboxax1aos.cloud.onebox.dynamics.com". 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". It will authenticate with the specified ClientId parameter: "dea8d7a9-1602-4429-b138-111111111111". It will authenticate with the specified ClientSecret parameter: "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522". ### EXAMPLE 2 ``` 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" ``` This will get all available service groups for the D365FO instance, which matches the "*TS*" as a name. It will contact the D365FO instance specified in the Url parameter: "https://usnconeboxax1aos.cloud.onebox.dynamics.com". 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". It will authenticate with the specified ClientId parameter: "dea8d7a9-1602-4429-b138-111111111111". It will authenticate with the specified ClientSecret parameter: "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522". It will limit the output to only those matching the specified Name parameter: "*TS*" ### EXAMPLE 3 ``` 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 ``` This will get all available service groups for the D365FO instance with the outer most hierarchy. It will contact the D365FO instance specified in the Url parameter: "https://usnconeboxax1aos.cloud.onebox.dynamics.com". 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". It will authenticate with the specified ClientId parameter: "dea8d7a9-1602-4429-b138-111111111111". It will authenticate with the specified ClientSecret parameter: "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522". ### EXAMPLE 4 ``` 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 ``` This will get all available service groups for the D365FO instance and display the result as json. It will contact the D365FO instance specified in the Url parameter: "https://usnconeboxax1aos.cloud.onebox.dynamics.com". 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". It will authenticate with the specified ClientId parameter: "dea8d7a9-1602-4429-b138-111111111111". It will authenticate with the specified ClientSecret parameter: "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522". ## PARAMETERS ### -Name The name of the json service that you are looking for Default value is "*" to display all json services ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -Url URL / URI for the D365FO environment you want to access If you are working against a D365FO instance, it will be the URL / URI for the instance itself If you are working against a D365 Talent / HR instance, this will have to be "http://hr.talent.dynamics.com" ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Tenant Azure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to access ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ClientId The ClientId obtained from the Azure Portal when you created a Registered Application ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 4 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ClientSecret The ClientSecret obtained from the Azure Portal when you created a Registered Application ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 5 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -RawOutput Instructs the cmdlet to include the outer structure of the response received from the endpoint The output will still be a PSCustomObject ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputAsJson Instructs the cmdlet to convert the output to a Json string ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### System.String ## NOTES Tags: DMF, OData, RestApi, Data Management Framework Author: Mötz Jensen (@Splaxi) Idea taken from http://www.ksaelen.be/wordpresses/dynamicsaxblog/2016/01/dynamics-ax-7-tip-what-services-are-exposed/ ## RELATED LINKS ================================================ FILE: docs/Get-D365Label.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365Label ## SYNOPSIS Get label from the label file from Dynamics 365 Finance & Operations environment ## SYNTAX ``` Get-D365Label [[-BinDir] ] [-LabelFileId] [[-Language] ] [[-Name] ] [] ``` ## DESCRIPTION Get label from the label file from the running the Dynamics 365 Finance & Operations instance ## EXAMPLES ### EXAMPLE 1 ``` Get-D365Label -LabelFileId PRO ``` Shows the entire list of labels that are available from the PRO label file. The language is defaulted to "en-US". ### EXAMPLE 2 ``` Get-D365Label -LabelFileId PRO -Language da ``` Shows the entire list of labels that are available from the PRO label file. Shows only all "da" (Danish) labels. ### EXAMPLE 3 ``` Get-D365Label -LabelFileId PRO -Name "@PRO59*" ``` Shows the labels available from the PRO label file where the name fits the search "@PRO59*" A result set example: Name Value Language ---- ----- -------- @PRO59 Indicates if the type of the rebate value. en-US @PRO594 Pack consumption en-US @PRO595 Pack qty now being released to production in the BOM unit. en-US @PRO596 Pack unit. en-US @PRO597 Pack proposal for release in the packing unit. en-US @PRO590 Constant pack qty en-US @PRO593 Pack proposal release in BOM unit. en-US @PRO598 Pack quantity now being released for the production in the packing unit. en-US ### EXAMPLE 4 ``` Get-D365Label -LabelFileId PRO -Name "@PRO59*" -Language da,en-us ``` Shows the labels available from the PRO label file where the name fits the search "@PRO59*". Shows for both "da" (Danish) and en-US (English) ## PARAMETERS ### -BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -LabelFileId Name / Id of the label "file" that you want to work against ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Language Name / string representation of the language / culture you want to work against Default value is "en-US" ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: En-US Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Name Name of the label that you are looking for Accepts wildcards for searching. E.g. -Name "@PRO59*" Default value is "*" which will search for all labels ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: PackagesLocalDirectory, Servicing, Language, Labels, Label Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Pedro Tornich" (twitter: @ptornich) All credits goes to him for showing how to extract these information His github repository can be found here: https://github.com/ptornich/LabelFileGenerator ## RELATED LINKS ================================================ FILE: docs/Get-D365LabelFile.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365LabelFile ## SYNOPSIS Get label file (ids) for packages / modules from Dynamics 365 Finance & Operations environment ## SYNTAX ``` Get-D365LabelFile [[-BinDir] ] [[-PackageDirectory] ] [[-Module] ] [[-Name] ] [] ``` ## DESCRIPTION Get label file (ids) for packages / modules from the machine running the AOS service for Dynamics 365 Finance & Operations ## EXAMPLES ### EXAMPLE 1 ``` Get-D365LabelFile ``` Shows the entire list of label file (ids) for all installed packages / modules located in the default location on the machine ### EXAMPLE 2 ``` Get-D365LabelFile -Name "Acc*Receivable*" ``` Shows the list of label file (ids) for all installed packages / modules where the label file (ids) name fits the search "Acc*Receivable*" A result set example: LabelFileId Languages Module ----------- --------- ------ AccountsReceivable {ar-AE, ar, cs, da...} ApplicationSuite AccountsReceivable_SalesTaxCodesSA {en-US} ApplicationSuite ### EXAMPLE 3 ``` Get-D365LabelFile -PackageDirectory "J:\AOSService\PackagesLocalDirectory" ``` Shows the list of label file (ids) for all installed packages / modules located in "J:\AOSService\PackagesLocalDirectory" on the machine ## PARAMETERS ### -BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### -Module Name of the module that you want to work against Default value is "*" which will search for all modules ```yaml Type: String Parameter Sets: (All) Aliases: ModuleName Required: False Position: 4 Default value: * Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Name Name of the label file (id) that you are looking for Accepts wildcards for searching. E.g. -Name "Acc*Receivable*" Default value is "*" which will search for all label file (ids) ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: PackagesLocalDirectory, Servicing, Language, Labels, Label Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Pedro Tornich" (twitter: @ptornich) All credits goes to him for showing how to extract these information His github repository can be found here: https://github.com/ptornich/LabelFileGenerator ## RELATED LINKS ================================================ FILE: docs/Get-D365Language.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365Language ## SYNOPSIS Get installed languages from Dynamics 365 Finance & Operations environment ## SYNTAX ``` Get-D365Language [[-BinDir] ] [[-Name] ] [] ``` ## DESCRIPTION Get installed languages from the running the Dynamics 365 Finance & Operations instance ## EXAMPLES ### EXAMPLE 1 ``` Get-D365Language ``` Shows the entire list of installed languages that are available from the running instance ### EXAMPLE 2 ``` Get-D365Language -Name "fr*" ``` Shows the list of installed languages where the name fits the search "fr*" A result set example: fr French fr-BE French (Belgium) fr-CA French (Canada) fr-CH French (Switzerland) ## PARAMETERS ### -BinDir Path to the directory containing the BinDir and its assemblies Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -Name Name of the language that you are looking for Accepts wildcards for searching. E.g. -Name "fr*" Default value is "*" which will search for all languages ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: PackagesLocalDirectory, Servicing, Language, Labels, Label Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Pedro Tornich" (twitter: @ptornich) All credits goes to him for showing how to extract these information His github repository can be found here: https://github.com/ptornich/LabelFileGenerator ## RELATED LINKS ================================================ FILE: docs/Get-D365LcsApiConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365LcsApiConfig ## SYNOPSIS Get the LCS configuration details ## SYNTAX ``` Get-D365LcsApiConfig [-OutputAsHashtable] [] ``` ## DESCRIPTION Get the LCS configuration details from the configuration store All settings retrieved from this cmdlets is to be considered the default parameter values across the different cmdlets ## EXAMPLES ### EXAMPLE 1 ``` Get-D365LcsApiConfig ``` This will output the current LCS API configuration. The object returned will be a PSCustomObject. ### EXAMPLE 2 ``` Get-D365LcsApiConfig -OutputAsHashtable ``` This will output the current LCS API configuration. The object returned will be a Hashtable. ## PARAMETERS ### -OutputAsHashtable Instruct the cmdlet to return a hashtable object ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, ClientId Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Get-D365LcsApiToken]() [Get-D365LcsAssetValidationStatus]() [Get-D365LcsDeploymentStatus]() [Invoke-D365LcsApiRefreshToken]() [Invoke-D365LcsDeployment]() [Invoke-D365LcsUpload]() [Set-D365LcsApiConfig]() ================================================ FILE: docs/Get-D365LcsApiToken.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365LcsApiToken ## SYNOPSIS Get a valid OAuth 2.0 access token for LCS ## SYNTAX ``` Get-D365LcsApiToken [[-ClientId] ] [-Username] [-Password] [[-LcsApiUri] ] [-EnableException] [] ``` ## 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 ## EXAMPLES ### EXAMPLE 1 ``` Get-D365LcsApiToken -ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" -Username "serviceaccount@domain.com" -Password "TopSecretPassword" -LcsApiUri "https://lcsapi.lcs.dynamics.com" ``` This will obtain a valid OAuth 2.0 access token from Azure Active Directory. The ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" is used in the OAuth 2.0 Grant Flow to authenticate. 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". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). ### EXAMPLE 2 ``` Get-D365LcsApiToken -ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" -Username "serviceaccount@domain.com" -Password "TopSecretPassword" -LcsApiUri "https://lcsapi.lcs.dynamics.com" | Set-D365LcsApiConfig -ProjectId 123456789 ``` This will obtain a valid OAuth 2.0 access token from Azure Active Directory. The ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" is used in the OAuth 2.0 Grant Flow to authenticate. 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". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). The output object received from Get-D365LcsApiToken is piped directly to Set-D365LcsApiConfig. 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. 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. ### EXAMPLE 3 ``` Get-D365LcsApiToken -Username "serviceaccount@domain.com" -Password "TopSecretPassword" ``` This will obtain a valid OAuth 2.0 access token from Azure Active Directory. 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". All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 4 ``` Get-D365LcsApiToken -Username "serviceaccount@domain.com" -Password "TopSecretPassword" | Set-D365LcsApiConfig ``` This will obtain a valid OAuth 2.0 access token from Azure Active Directory and save the needed details. 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". The output object received from Get-D365LcsApiToken is piped directly to Set-D365LcsApiConfig. Set-D365LcsApiConfig will save the access_token(BearerToken), refresh_token(RefreshToken) and expires_on(ActiveTokenExpiresOn). All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ## PARAMETERS ### -ClientId The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:LcsApiClientId Accept pipeline input: False Accept wildcard characters: False ``` ### -Username The username of the account that you want to impersonate It can either be your personal account or a service account ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Password The password of the account that you want to impersonate ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Get-D365LcsApiConfig]() [Get-D365LcsAssetValidationStatus]() [Get-D365LcsDeploymentStatus]() [Invoke-D365LcsApiRefreshToken]() [Invoke-D365LcsDeployment]() [Invoke-D365LcsUpload]() [Set-D365LcsApiConfig]() ================================================ FILE: docs/Get-D365LcsAssetFile.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365LcsAssetFile ## SYNOPSIS Get file from the Asset library inside the LCS project ## SYNTAX ``` Get-D365LcsAssetFile [[-ProjectId] ] [[-FileType] ] [[-AssetName] ] [[-AssetVersion] ] [[-AssetFilename] ] [[-AssetDescription] ] [[-AssetId] ] [[-BearerToken] ] [[-LcsApiUri] ] [-Latest] [[-RetryTimeout] ] [-EnableException] [] ``` ## DESCRIPTION Get the available files from the Asset Library in LCS project ## EXAMPLES ### EXAMPLE 1 ``` Get-D365LcsAssetFile -ProjectId 123456789 -FileType SoftwareDeployablePackage -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" ``` This will list all Software Deployable Packages. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). ### EXAMPLE 2 ``` Get-D365LcsAssetFile -FileType SoftwareDeployablePackage ``` This will list all Software Deployable Packages. It will search for SoftwareDeployablePackage by using the FileType parameter. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 3 ``` Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetFilename "*MAIN*" ``` This will list all Software Deployable Packages, that matches the "*MAIN*" search pattern in the AssetFilename. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetFilename "*MAIN*" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 4 ``` Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetName "*MAIN*" ``` This will list all Software Deployable Packages, that matches the "*MAIN*" search pattern in the AssetName. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetName "*MAIN*" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 5 ``` Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetDescription "*TEST*" ``` This will list all Software Deployable Packages, that matches the "*TEST*" search pattern in the AssetDescription. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetDescription "*TEST*" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 6 ``` Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetId "500dd860-eacf-4e04-9f18-f9c8fe1d8e03" ``` This will list all Software Deployable Packages, that matches the "500dd860-eacf-4e04-9f18-f9c8fe1d8e03" search pattern in the AssetId. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetId "500dd860-eacf-4e04-9f18-f9c8fe1d8e03" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 7 ``` Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -Latest | Invoke-D365AzCopyTransfer -DestinationUri C:\Temp\d365fo.tools -FileName "Main.zip" -ShowOriginalProgress ``` This will download the latest Software Deployable Package from the Asset Library in LCS onto your on machine. It will list Software Deployable Packages based on the FileType parameter. It will list the latest (newest) Software Deployable Package. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 8 ``` Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -RetryTimeout "00:01:00" ``` This will list all Software Deployable Packages, and allow for the cmdlet to retry for no more than 1 minute. It will search for SoftwareDeployablePackage by using the FileType parameter. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -FileType Type of file you want to list from the LCS Asset Library Valid options: "Model" "Process Data Package" "Software Deployable Package" "GER Configuration" "Data Package" "PowerBI Report Model" "E-Commerce Package" "NuGet Package" "Retail Self-Service Package" "Commerce Cloud Scale Unit Extension" Default value is "Software Deployable Package" ```yaml Type: LcsAssetFileType Parameter Sets: (All) Aliases: Accepted values: Model, ProcessDataPackage, SoftwareDeployablePackage, GERConfiguration, DataPackage, PowerBIReportModel, ECommercePackage, NuGetPackage, RetailSelfServicePackage, CommerceCloudScaleUnitExtension Required: False Position: 2 Default value: SoftwareDeployablePackage Accept pipeline input: False Accept wildcard characters: False ``` ### -AssetName Name of the asset that you are looking for Accepts wildcards for searching. E.g. -AssetName "*ISV*" Default value is "*" which will search for all assets via the Name property ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -AssetVersion Version of the Asset file that you are looking for It does a simple compare against the response from LCS and only lists the ones that matches Accepts wildcards for searching. E.g. -AssetVersion "*ISV*" Default value is "*" which will search for all files ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -AssetFilename Name of the file that you are looking for Accepts wildcards for searching. E.g. -AssetFilename "*ISV*" Default value is "*" which will search for all files via the FileName property ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -AssetDescription Name of the file that you are looking for Accepts wildcards for searching. E.g. -AssetDescription "*ISV*" Default value is "*" which will search for all files via the FileDescription property ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -AssetId Id of the file that you are looking for Accepts wildcards for searching. E.g. -AssetId "*ISV*" Default value is "*" which will search for all files via the AssetId property ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: 8 Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 9 Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -Latest Instruct the cmdlet to only fetch the latest file from the Asset Library from LCS ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: GetLatest Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: 10 Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Get-D365LcsApiConfig]() [Get-D365LcsApiToken]() [Invoke-D365LcsApiRefreshToken]() [Set-D365LcsApiConfig]() [Get-D365LcsSharedAssetFile]() ================================================ FILE: docs/Get-D365LcsAssetValidationStatus.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365LcsAssetValidationStatus ## SYNOPSIS Get the validation status from LCS ## SYNTAX ``` Get-D365LcsAssetValidationStatus [-AssetId] [[-ProjectId] ] [[-BearerToken] ] [[-LcsApiUri] ] [-WaitForValidation] [[-SleepInSeconds] ] [[-RetryTimeout] ] [-EnableException] [] ``` ## DESCRIPTION Get the validation status for a given file in the Asset Library in LCS ## EXAMPLES ### EXAMPLE 1 ``` Get-D365LcsAssetValidationStatus -ProjectId 123456789 -BearerToken "JldjfafLJdfjlfsalfd..." -AssetId "958ae597-f089-4811-abbd-c1190917eaae" -LcsApiUri "https://lcsapi.lcs.dynamics.com" ``` This will check the validation status for the file in the Asset Library. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. 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. The request will authenticate with the BearerToken "Bearer JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). ### EXAMPLE 2 ``` Get-D365LcsAssetValidationStatus -AssetId "958ae597-f089-4811-abbd-c1190917eaae" ``` This will check the validation status for the file in the Asset Library. 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. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 3 ``` Get-D365LcsAssetValidationStatus -AssetId "958ae597-f089-4811-abbd-c1190917eaae" -WaitForValidation ``` This will check the validation status for the file in the Asset Library. 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. The cmdlet will every 60 seconds contact the LCS API endpoint and check if the status of the validation is either success or failure. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 4 ``` Invoke-D365LcsUpload -FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip" | Get-D365LcsAssetValidationStatus -WaitForValidation ``` This will start the upload of a file to the Asset Library and check the validation status for the file in the Asset Library. The file that will be uploaded is based on the FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip". The output object received from Invoke-D365LcsUpload is piped directly to Get-D365LcsAssetValidationStatus. The cmdlet will every 60 seconds contact the LCS API endpoint and check if the status of the validation is either success or failure. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 5 ``` Get-D365LcsAssetValidationStatus -AssetId "958ae597-f089-4811-abbd-c1190917eaae" -RetryTimeout "00:01:00" ``` 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. 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. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ## PARAMETERS ### -AssetId The unique id of the asset / file that you are trying to deploy from LCS ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: 3 Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -WaitForValidation Instruct the cmdlet to wait for the validation process to complete The cmdlet will sleep for 60 seconds, before requesting the status of the validation process from LCS ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -SleepInSeconds Time in seconds that you want the cmdlet to use as the sleep timer between each request against the LCS endpoint Default value is 60 ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: 60 Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Get-D365LcsApiConfig]() [Get-D365LcsApiToken]() [Get-D365LcsDeploymentStatus]() [Invoke-D365LcsApiRefreshToken]() [Invoke-D365LcsDeployment]() [Invoke-D365LcsUpload]() [Set-D365LcsApiConfig]() ================================================ FILE: docs/Get-D365LcsDatabaseBackups.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365LcsDatabaseBackups ## SYNOPSIS Get database backups from LCS project ## SYNTAX ``` Get-D365LcsDatabaseBackups [[-ProjectId] ] [[-BearerToken] ] [[-LcsApiUri] ] [-Latest] [[-RetryTimeout] ] [-EnableException] [] ``` ## DESCRIPTION Get the available database backups from the Asset Library in LCS project ## EXAMPLES ### EXAMPLE 1 ``` Get-D365LcsDatabaseBackups -ProjectId 123456789 -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" ``` This will get all available database backups from the Asset Library inside LCS. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The request will authenticate with the BearerToken "Bearer JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). ### EXAMPLE 2 ``` Get-D365LcsDatabaseBackups ``` This will get all available database backups from the Asset Library inside LCS. It will use default values for all parameters. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 3 ``` Get-D365LcsDatabaseBackups -Latest ``` This will get the latest available database backup from the Asset Library inside LCS. It will use default values for all parameters. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 4 ``` Get-D365LcsDatabaseBackups -Latest -RetryTimeout "00:01:00" ``` 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. It will use default values for all parameters. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: 2 Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -Latest Instruct the cmdlet to only fetch the latest file from the Azure Storage Account ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: GetLatest Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Get-D365LcsApiConfig]() [Get-D365LcsApiToken]() [Invoke-D365LcsApiRefreshToken]() [Set-D365LcsApiConfig]() ================================================ FILE: docs/Get-D365LcsDatabaseOperationStatus.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365LcsDatabaseOperationStatus ## SYNOPSIS Get the status of a database operation from LCS ## SYNTAX ``` Get-D365LcsDatabaseOperationStatus [[-ProjectId] ] [[-BearerToken] ] [-OperationActivityId] [-EnvironmentId] [[-LcsApiUri] ] [-WaitForCompletion] [[-SleepInSeconds] ] [[-RetryTimeout] ] [-EnableException] [] ``` ## DESCRIPTION Get the current status of a database operation against an environment from a LCS project ## EXAMPLES ### EXAMPLE 1 ``` Get-D365LcsDatabaseOperationStatus -ProjectId 123456789 -OperationActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" ``` This will check the database operation status of a specific OperationActivityId against an environment. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). ### EXAMPLE 2 ``` Get-D365LcsDatabaseOperationStatus -OperationActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" ``` This will check the database operation status of a specific OperationActivityId against an environment. The OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 3 ``` Get-D365LcsDatabaseOperationStatus -OperationActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -WaitForCompletion ``` This will check the database operation status of a specific OperationActivityId against an environment. The OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. 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. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 4 ``` Get-D365LcsDatabaseOperationStatus -OperationActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -RetryTimeout "00:01:00" ``` 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. The OperationActivityId is identified by the OperationActivityId 123456789, which is obtained from executing either the Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: 2 Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -OperationActivityId The unique id of the operaction activity that identitfies the database operation It will be part of the output from the different Invoke-D365LcsDatabaseExport or Invoke-D365LcsDatabaseRefresh cmdlets ```yaml Type: String Parameter Sets: (All) Aliases: ActivityId Required: True Position: 3 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -EnvironmentId The unique id of the environment that you want to work against The Id can be located inside the LCS portal ```yaml Type: String Parameter Sets: (All) Aliases: SourceEnvironmentId Required: True Position: 4 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -WaitForCompletion Instruct the cmdlet to wait for the deployment process to complete The cmdlet will sleep for 300 seconds, before requesting the status of the deployment process from LCS ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -SleepInSeconds Time in seconds that you want the cmdlet to use as the sleep timer between each request against the LCS endpoint Default value is 300 ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: 300 Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### PSCustomObject ## NOTES Tags: Environment, Config, Configuration, LCS, Database backup, Api, Backup, Restore, Refresh Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Get-D365LcsApiConfig]() [Get-D365LcsApiToken]() [Get-D365LcsAssetValidationStatus]() [Invoke-D365LcsApiRefreshToken]() [Invoke-D365LcsDeployment]() [Invoke-D365LcsUpload]() [Set-D365LcsApiConfig]() ================================================ FILE: docs/Get-D365LcsDeploymentStatus.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365LcsDeploymentStatus ## SYNOPSIS Get the Deployment status from LCS ## SYNTAX ``` Get-D365LcsDeploymentStatus [[-ProjectId] ] [[-BearerToken] ] [-ActivityId] [-EnvironmentId] [[-LcsApiUri] ] [-WaitForCompletion] [[-SleepInSeconds] ] [-FailOnErrorMessage] [[-RetryTimeout] ] [-EnableException] [] ``` ## DESCRIPTION Get the Deployment status for activity against an environment from the Dynamics LCS Portal ## EXAMPLES ### EXAMPLE 1 ``` Get-D365LcsDeploymentStatus -ProjectId 123456789 -ActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -BearerToken "Bearer JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" ``` This will check the deployment status of specific activity against an environment. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "Bearer JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). ### EXAMPLE 2 ``` Get-D365LcsDeploymentStatus -ActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" ``` This will check the deployment status of specific activity against an environment. The activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 3 ``` Get-D365LcsDeploymentStatus -ActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -WaitForCompletion ``` This will check the deployment status of specific activity against an environment. The activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The cmdlet will every 300 seconds contact the LCS API endpoint and check if the status of the deployment is either success or failure. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 4 ``` Get-D365LcsDeploymentStatus -ActivityId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -RetryTimeout "00:01:00" ``` 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. The activity is identified by the ActivityId 123456789, which is obtained from the Invoke-D365LcsDeployment execution. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: 2 Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -ActivityId The unique id of the action that you started from the Invoke-D365LcsDeployment cmdlet ```yaml Type: String Parameter Sets: (All) Aliases: ActionHistoryId Required: True Position: 3 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -EnvironmentId The unique id of the environment that you want to work against The Id can be located inside the LCS portal ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 4 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -WaitForCompletion Instruct the cmdlet to wait for the deployment process to complete The cmdlet will sleep for 300 seconds, before requesting the status of the deployment process from LCS ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -SleepInSeconds Time in secounds that you want the cmdlet to use as the sleep timer between each request against the LCS endpoint Default value is 300 ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: 300 Accept pipeline input: False Accept wildcard characters: False ``` ### -FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### PSCustomObject ## NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deploy Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Get-D365LcsApiConfig]() [Get-D365LcsApiToken]() [Get-D365LcsAssetValidationStatus]() [Invoke-D365LcsApiRefreshToken]() [Invoke-D365LcsDeployment]() [Invoke-D365LcsUpload]() [Set-D365LcsApiConfig]() ================================================ FILE: docs/Get-D365LcsEnvironmentHistory.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365LcsEnvironmentHistory ## SYNOPSIS Get history for a given environment within a LCS project ## SYNTAX ### Default (Default) ``` Get-D365LcsEnvironmentHistory [-ProjectId ] [-BearerToken ] -EnvironmentId [-LcsApiUri ] [-FailOnErrorMessage] [-RetryTimeout ] [-EnableException] [] ``` ### Pagination ``` Get-D365LcsEnvironmentHistory [-ProjectId ] [-BearerToken ] -EnvironmentId [-TraverseAllPages] [-FirstPages ] [-LcsApiUri ] [-FailOnErrorMessage] [-RetryTimeout ] [-EnableException] [] ``` ## DESCRIPTION Get history details for a given environment from within a LCS project There can be multiple pages of data, which requires you to use the TraverseAllPages parameter, if you want all data to be shown ## EXAMPLES ### EXAMPLE 1 ``` Get-D365LcsEnvironmentHistory -ProjectId "123456789" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" ``` This will list the first page of Environment History Data from the LCS API. The LCS project is identified by the ProjectId "123456789", which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. A result set example: Name : Service Update - 10.0.19 Type : SFBinaryHotfix TypeDisplay : Binary hotfix StartDateTimeUTC : 2021-07-11T00:01:57.423 EndDateTimeUTC : 2021-07-11T05:01:12.97 Status : Completed ActivityId : e3509860-61d4-4003-9b45-6ea7d89aea30 EnvironmentId : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e ProjectId : 123456789 Name : Refresh database Type : SFSourceDbToSandbox TypeDisplay : Refresh database StartDateTimeUTC : 2021-06-06T15:17:48.87 EndDateTimeUTC : 2021-06-06T16:33:40.367 Status : Completed ActivityId : e3509860-61d4-4003-9b45-6ea7d89aea31 EnvironmentId : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e ProjectId : 123456789 Name : Export database Type : SFExportSandboxDb TypeDisplay : Export database StartDateTimeUTC : 2021-04-27T22:08:01.103 EndDateTimeUTC : 2021-04-28T23:30:06.623 Status : RollbackCompleted ActivityId : e3509860-61d4-4003-9b45-6ea7d89aea32 EnvironmentId : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e ProjectId : 123456789 Name : Main_2021.1.1.1 Type : SFApplicationHotfix TypeDisplay : Application deployable package StartDateTimeUTC : 2021-03-04T21:44:20.793 EndDateTimeUTC : 2021-03-04T22:48:17.303 Status : Completed ActivityId : e3509860-61d4-4003-9b45-6ea7d89aea33 EnvironmentId : 13cc7700-c13b-4ea3-81cd-2d26fa72ec5e ProjectId : 123456789 ### EXAMPLE 2 ``` Get-D365LcsEnvironmentHistory -ProjectId "123456789" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -TraverseAllPages ``` This will list the all the pages of Environment History Data from the LCS API. The LCS project is identified by the ProjectId "123456789", which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The cmdlet will TraverseAllPages from the LCS API. It will use the default value for the maximum number of pages to return, 99 pages. TraverseAllPages will increase the request time for completion, based on how many entries there is in the history. Please be patient and let the system work for you. Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint ### EXAMPLE 3 ``` Get-D365LcsEnvironmentHistory -ProjectId "123456789" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -TraverseAllPages -FirstPages 2 ``` This will list the all the pages of Environment History Data from the LCS API. The LCS project is identified by the ProjectId "123456789", which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The cmdlet will TraverseAllPages from the LCS API. The cmdlet will be fetching the FirstPages 2, to limit the output from the cmdlet to only the newest 2 pages. TraverseAllPages will increase the request time for completion, based on how many entries there is in the history. Please be patient and let the system work for you. Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: Named Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -EnvironmentId Id of the environment that you want to be working against ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -TraverseAllPages Instruct the cmdlet to fetch all pages, until there isn't more data available This can be a slow operation, as it has to call the LCS API multiple times, fetching a single page per call ```yaml Type: SwitchParameter Parameter Sets: Pagination Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -FirstPages Instruct the cmdlet how many pages that you want it to retrieve from the LCS API Can only be used in combination with -TraverseAllPages The default value is: 99 pages, which should be more than enough Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint ```yaml Type: Int32 Parameter Sets: Pagination Aliases: Required: False Position: Named Default value: 99 Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: Named Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### PSCustomObject ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365LcsEnvironmentMetadata.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365LcsEnvironmentMetadata ## SYNOPSIS Get LCS environment meta data from within a project ## SYNTAX ### Default (Default) ``` Get-D365LcsEnvironmentMetadata [-ProjectId ] [-BearerToken ] [-LcsApiUri ] [-FailOnErrorMessage] [-RetryTimeout ] [-EnableException] [] ``` ### SearchByEnvironmentId ``` Get-D365LcsEnvironmentMetadata [-ProjectId ] [-BearerToken ] [-EnvironmentId ] [-LcsApiUri ] [-FailOnErrorMessage] [-RetryTimeout ] [-EnableException] [] ``` ### SearchByEnvironmentName ``` Get-D365LcsEnvironmentMetadata [-ProjectId ] [-BearerToken ] [-EnvironmentName ] [-LcsApiUri ] [-FailOnErrorMessage] [-RetryTimeout ] [-EnableException] [] ``` ### Pagination ``` Get-D365LcsEnvironmentMetadata [-ProjectId ] [-BearerToken ] [-TraverseAllPages] [-FirstPages ] [-LcsApiUri ] [-FailOnErrorMessage] [-RetryTimeout ] [-EnableException] [] ``` ## DESCRIPTION Get all meta data details for environments from within a LCS project It supports listing all environments, but also supports single / specific environments by searching based on EnvironmentId or EnvironmentName ## EXAMPLES ### EXAMPLE 1 ``` Get-D365LcsEnvironmentMetadata -ProjectId "123456789" ``` This will show metadata for every available environment from the LCS project. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The request time for completion is directly impacted by the number of environments within the LCS project. Please be patient and let the system work for you. 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. A result set example (Tier1): EnvironmentId : c6566087-23bd-4561-8247-4d7f4efd3172 EnvironmentName : DevBox-01 ProjectId : 123456789 EnvironmentInfrastructure : CustomerManaged EnvironmentType : DevTestDev EnvironmentGroup : Primary EnvironmentProduct : Finance and Operations EnvironmentEndpointBaseUrl : https://devbox-4d7f4efd3172devaos.cloudax.dynamics.com/ DeploymentState : Stopped TopologyDisplayName : Finance and Operations - Develop (10.0.18 with Platform update 42) CurrentApplicationBuildVersion : 10.0.793.41 CurrentApplicationReleaseName : 10.0.18 CurrentPlatformReleaseName : Update42 CurrentPlatformVersion : 7.0.5968.16999 DeployedOnUTC : 7/5/2021 11:19 AM CloudStorageLocation : West Europe DisasterRecoveryLocation : North Europe DeploymentStatusDisplay : Stopped CanStart : True CanStop : False A result set example (Tier2+): EnvironmentId : e7c53b85-8b6a-4ab9-8985-1e1ea89a0f0a EnvironmentName : Contoso-SIT ProjectId : 123456789 EnvironmentInfrastructure : SelfService EnvironmentType : Sandbox EnvironmentGroup : Primary EnvironmentProduct : Finance and Operations EnvironmentEndpointBaseUrl : https://Contoso-SIT.sandbox.operations.dynamics.com/ DeploymentState : Finished TopologyDisplayName : AXHA CurrentApplicationBuildVersion : 10.0.761.10019 CurrentApplicationReleaseName : 10.0.17 CurrentPlatformReleaseName : PU41 CurrentPlatformVersion : 7.0.5934.35741 DeployedOnUTC : 4/1/2020 9:35 PM CloudStorageLocation : West Europe DisasterRecoveryLocation : DeploymentStatusDisplay : Deployed CanStart : False CanStop : False A result set example (PROD): EnvironmentId : a8aab4f4-d4f3-41f0-af80-54cea83b50d2 EnvironmentName : Contoso-PROD ProjectId : 123456789 EnvironmentInfrastructure : SelfService EnvironmentType : Production EnvironmentGroup : Primary EnvironmentProduct : Finance and Operations EnvironmentEndpointBaseUrl : https://Contoso-PROD.operations.dynamics.com/ DeploymentState : Finished TopologyDisplayName : AXHA CurrentApplicationBuildVersion : 10.0.886.48 CurrentApplicationReleaseName : 10.0.20 CurrentPlatformReleaseName : PU44 CurrentPlatformVersion : 7.0.6060.45 DeployedOnUTC : 4/9/2020 12:11 PM CloudStorageLocation : West Europe DisasterRecoveryLocation : DeploymentStatusDisplay : Deployed CanStart : False CanStop : False ### EXAMPLE 2 ``` Get-D365LcsEnvironmentMetadata -ProjectId "123456789" -TraverseAllPages ``` This will show metadata for every available environment from the LCS project, across multiple pages. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. It will use the default value for the maximum number of pages to return, 99 pages. TraverseAllPages will increase the request time for completion, based on how many entries there is in the history. Please be patient and let the system work for you. Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint ### EXAMPLE 3 ``` Get-D365LcsEnvironmentMetadata -ProjectId "123456789" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" ``` This will show metadata for every available environment from the LCS project. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. ### EXAMPLE 4 ``` Get-D365LcsEnvironmentMetadata -ProjectId "123456789" -EnvironmentName "Contoso-SIT" ``` This will show metadata for every available environment from the LCS project. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentName "Contoso-SIT", which can be obtained in the LCS portal. ### EXAMPLE 5 ``` Get-D365LcsEnvironmentMetadata -ProjectId "123456789" -TraverseAllPages -FirstPages 2 ``` This will show metadata for every available environment from the LCS project, across multiple pages. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. It will use the default value for the maximum number of pages to return, 99 pages. The cmdlet will be fetching the FirstPages 2, to limit the output from the cmdlet to only the newest 2 pages. TraverseAllPages will increase the request time for completion, based on how many entries there is in the history. Please be patient and let the system work for you. Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: Named Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -EnvironmentId Id of the environment that you want to be working against ```yaml Type: String Parameter Sets: SearchByEnvironmentId Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -EnvironmentName Name of the environment that you want to be working against ```yaml Type: String Parameter Sets: SearchByEnvironmentName Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -TraverseAllPages Instruct the cmdlet to fetch all pages, until there isn't more data available This can be a slow operation, as it has to call the LCS API multiple times, fetching a single page per call ```yaml Type: SwitchParameter Parameter Sets: Pagination Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -FirstPages Instruct the cmdlet how many pages that you want it to retrieve from the LCS API Can only be used in combination with -TraverseAllPages The default value is: 99 pages, which should be more than enough Please note that when fetching more than 6-7 pages, you will start hitting the 429 throttling from the LCS API endpoint ```yaml Type: Int32 Parameter Sets: Pagination Aliases: Required: False Position: Named Default value: 99 Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: Named Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### PSCustomObject ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365LcsEnvironmentRsatCertificate.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365LcsEnvironmentRsatCertificate ## SYNOPSIS Get LCS environment rsat certificate from within a project ## SYNTAX ``` Get-D365LcsEnvironmentRsatCertificate [[-ProjectId] ] [[-BearerToken] ] [-EnvironmentId] [[-OutputPath] ] [[-LcsApiUri] ] [-FailOnErrorMessage] [[-RetryTimeout] ] [-EnableException] [] ``` ## DESCRIPTION Download and persist the active rsat certificate from environments from within a LCS project ## EXAMPLES ### EXAMPLE 1 ``` Get-D365LcsEnvironmentRsatCertificate -ProjectId "123456789" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" ``` This will download the active rsat certificate file for the environment from the LCS project. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. A result set example: Path : c:\temp\d365fo.tools\RsatCert\RSATCertificate_ABC-UAT_20240101-012030 CerFile : C:\temp\d365fo.tools\RsatCert\RSATCertificate_ABC-UAT_20240101-012030\RSATCertificate_ABC-UAT_20240101-012030.cer PfxFile : C:\temp\d365fo.tools\RsatCert\RSATCertificate_ABC-UAT_20240101-012030\RSATCertificate_ABC-UAT_20240101-012030.pfx FileName : RSATCertificate_ABC-UAT_20240101-012030.zip Password : 9zbPiLMTk676mkq5FvqQ ### EXAMPLE 2 ``` Get-D365LcsEnvironmentRsatCertificate -ProjectId "123456789" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" | Import-D365RsatSelfServiceCertificates ``` This will download the active rsat certificate file for the environment from the LCS project. The resulting files are then imported into the certificate store on the local machine. ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: 2 Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -EnvironmentId Id of the environment that you want to be working against ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputPath Path to where you want the certificate files to be saved The default value is: "c:\temp\d365fo.tools\RsatCert\" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $(Join-Path $Script:DefaultTempPath "RsatCert") Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### PSCustomObject ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365LcsSharedAssetFile.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365LcsSharedAssetFile ## SYNOPSIS Get information for assets from the shared asset library of LCS ## SYNTAX ``` Get-D365LcsSharedAssetFile [[-ProjectId] ] [[-FileType] ] [[-AssetName] ] [[-AssetVersion] ] [[-AssetFilename] ] [[-AssetDescription] ] [[-AssetId] ] [[-BearerToken] ] [[-LcsApiUri] ] [-Latest] [-SkipSasGeneration] [[-RetryTimeout] ] [-EnableException] [] ``` ## DESCRIPTION Get the information for the file assets from the shared asset library of LCS matching the search criteria ## EXAMPLES ### EXAMPLE 1 ``` Get-D365LcsSharedAssetFile -ProjectId 123456789 -FileType SoftwareDeployablePackage -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" ``` This will list all Software Deployable Packages in the shared asset library. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). ### EXAMPLE 2 ``` Get-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage ``` This will list all Software Deployable Packages in the shared asset library. It will search for SoftwareDeployablePackage by using the FileType parameter. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 3 ``` Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetFilename "*MAIN*" ``` 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. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetFilename "*MAIN*" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 4 ``` Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetName "*MAIN*" ``` This will list all Software Deployable Packages in the shared asset library that match the "*MAIN*" search pattern in the name of the asset. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetName "*MAIN*" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 5 ``` Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetDescription "*TEST*" ``` This will list all Software Deployable Packages in the shared asset library that match the "*TEST*" search pattern in the asset description. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetDescription "*TEST*" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 6 ``` Get-D365LcsAssetFile -FileType SoftwareDeployablePackage -AssetId "500dd860-eacf-4e04-9f18-f9c8fe1d8e03" ``` 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. It will search for SoftwareDeployablePackage by using the FileType parameter. It will filter the output to match the AssetId "500dd860-eacf-4e04-9f18-f9c8fe1d8e03" search pattern. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 7 ``` $asset = Get-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage -Latest ``` PS C:\\\> Invoke-D365AzCopyTransfer -SourceUri $asset.FileLocation -DestinationUri C:\Temp\d365fo.tools\$($asset.Filename) -ShowOriginalProgress This will download the latest Software Deployable Package from the shared asset library in LCS onto your local machine. It will list Software Deployable Packages based on the FileType parameter. It will list the latest (newest) Software Deployable Package. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 8 ``` Get-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage -RetryTimeout "00:01:00" ``` 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. It will search for SoftwareDeployablePackage by using the FileType parameter. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 9 ``` Get-D365LcsSharedAssetFile -FileType SoftwareDeployablePackage -SkipSasGeneration ``` This will list all Software Deployable Packages in the shared asset library, but skip the SAS / Download generation It will search for SoftwareDeployablePackage by using the FileType parameter. This will increase the speed getting the list of assets - but you will not get a downloadable link. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig Although the assets are stored in the shared asset library, their information is retrieved in context of a project to get the full information. ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -FileType Type of file you want to list from the LCS Asset Library Valid options: "Model" "Process Data Package" "Software Deployable Package" "GER Configuration" "Data Package" "PowerBI Report Model" "E-Commerce Package" "NuGet Package" "Retail Self-Service Package" "Commerce Cloud Scale Unit Extension" Default value is "Software Deployable Package" ```yaml Type: LcsAssetFileType Parameter Sets: (All) Aliases: Accepted values: Model, ProcessDataPackage, SoftwareDeployablePackage, GERConfiguration, DataPackage, PowerBIReportModel, ECommercePackage, NuGetPackage, RetailSelfServicePackage, CommerceCloudScaleUnitExtension Required: False Position: 2 Default value: SoftwareDeployablePackage Accept pipeline input: False Accept wildcard characters: False ``` ### -AssetName Name of the asset that you are looking for Accepts wildcards for searching. E.g. -AssetName "*ISV*" Default value is "*" which will search for all assets via the Name property ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -AssetVersion Version of the Asset file that you are looking for It does a simple compare against the response from LCS and only lists the ones that matches Accepts wildcards for searching. E.g. -AssetVersion "*ISV*" Default value is "*" which will search for all files ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -AssetFilename Name of the file that you are looking for Accepts wildcards for searching. E.g. -AssetFilename "*ISV*" Default value is "*" which will search for all files via the FileName property ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -AssetDescription Name of the file that you are looking for Accepts wildcards for searching. E.g. -AssetDescription "*ISV*" Default value is "*" which will search for all files via the FileDescription property ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -AssetId Id of the file that you are looking for Accepts wildcards for searching. E.g. -AssetId "*ISV*" Default value is "*" which will search for all files via the AssetId property ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: 8 Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 9 Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -Latest Instruct the cmdlet to only fetch the latest file from the Asset Library from LCS ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: GetLatest Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -SkipSasGeneration Instruct the cmdlet to only fetch the meta data from the asset file (entry) This is to speed up the listing of entries, in some of the larger areas in the Shared Asset Library ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: 10 Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts Usually this parameter is not used directly, but via the Enable-D365Exception cmdlet See https://github.com/d365collaborative/d365fo.tools/wiki/Exception-handling#what-does-the--enableexception-parameter-do for further information ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Florian Hopfner (@FH-Inway) ## RELATED LINKS [Get-D365LcsApiConfig]() [Get-D365LcsApiToken]() [Invoke-D365LcsApiRefreshToken]() [Set-D365LcsApiConfig]() [Get-D365LcsAssetFile]() ================================================ FILE: docs/Get-D365MaintenanceMode.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365MaintenanceMode ## SYNOPSIS Get the maintenance mode status of the environment ## SYNTAX ``` Get-D365MaintenanceMode [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [] ``` ## DESCRIPTION Get the maintenance mode status of the Dynamics 365 environment to make sure that things are in the correct state ## EXAMPLES ### EXAMPLE 1 ``` Get-D365MaintenanceMode ``` This will get the current state of the maintenance mode of the environment ## PARAMETERS ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: MaintenanceMode, Maintenance, License, Configuration, Servicing Author: Mötz Jensen (@splaxi) ## RELATED LINKS [Enable-D365MaintenanceMode]() [Disable-D365MaintenanceMode]() ================================================ FILE: docs/Get-D365Model.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365Model ## SYNOPSIS Get available model from Dynamics 365 Finance & Operations environment ## SYNTAX ``` Get-D365Model [[-Name] ] [[-Module] ] [-CustomizableOnly] [-ExcludeMicrosoftModels] [-ExcludeBinaryModels] [[-BinDir] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Get available model from the machine running the AOS service for Dynamics 365 Finance & Operations ## EXAMPLES ### EXAMPLE 1 ``` Get-D365Model ``` Shows the entire list of installed models located in the default location on the machine. A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- AccountsPayableMobile AccountsPayableMobile False DoNotAllow 895571380 Microsoft Corporation ApplicationCommon ApplicationCommon False DoNotAllow 8956718 Microsoft ApplicationFoundation ApplicationFoundation False Allow 450 Microsoft Corporation IsvFoundation IsvFoundation True Allow 895972027 Isv Corp IsvLicense IsvLicense True DoNotAllow 895972028 Isv Corp ### EXAMPLE 2 ``` Get-D365Model -CustomizableOnly ``` Shows only the models that are marked as customizable. Will only include models that is Customization = "Allow". A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- ApplicationFoundation ApplicationFoundation False Allow 450 Microsoft Corporation ApplicationPlatform ApplicationPlatform False Allow 400 Microsoft Corporation ApplicationPlatformFormAdaptor ApplicationPlatformFormAdaptor False Allow 855030 Microsoft Corporation IsvFoundation IsvFoundation True Allow 895972027 Isv Corp ### EXAMPLE 3 ``` Get-D365Model -ExcludeMicrosoftModels ``` Shows only the models that doesn't have "Microsoft" in the publisher. Will only include models that is Publisher -NotLike "Microsoft*". A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- IsvFoundation IsvFoundation True Allow 895972027 Isv Corp IsvLicense IsvLicense True DoNotAllow 895972028 Isv Corp ### EXAMPLE 4 ``` Get-D365Model -ExcludeBinaryModels ``` Shows only the models that are NOT binary. Will only include models that is IsBinary = "False". A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- AccountsPayableMobile AccountsPayableMobile False DoNotAllow 895571380 Microsoft Corporation ApplicationCommon ApplicationCommon False DoNotAllow 8956718 Microsoft ApplicationFoundation ApplicationFoundation False Allow 450 Microsoft Corporation ### EXAMPLE 5 ``` Get-D365Model -CustomizableOnly -ExcludeMicrosoftModels ``` Shows only the models that are marked as customizable and NOT from Microsoft. Will only include models that is Customization = "Allow". Will only include models that is Publisher -NotLike "Microsoft*". A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- IsvFoundation IsvFoundation True Allow 895972027 Isv Corp ### EXAMPLE 6 ``` Get-D365Model -Name "Application*Adaptor" ``` Shows the list of models where the name fits the search "Application*Adaptor". A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- ApplicationFoundationFormAd... ApplicationFoundationFormAd... False DoNotAllow 855029 Microsoft Corporation ApplicationPlatformFormAdaptor ApplicationPlatformFormAdaptor False Allow 855030 Microsoft Corporation ApplicationSuiteFormAdaptor ApplicationSuiteFormAdaptor False DoNotAllow 855028 Microsoft Corporation ApplicationWorkspacesFormAd... ApplicationWorkspacesFormAd... False DoNotAllow 855066 Microsoft Corporation ### EXAMPLE 7 ``` Get-D365Model -Module ApplicationSuite ``` Shows only the models that are inside the ApplicationSuite module. A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- Electronic Reporting Applic... ApplicationSuite False DoNotAllow 855009 Microsoft Corporation Foundation ApplicationSuite False DoNotAllow 17 Microsoft Corporation SCMControls ApplicationSuite False DoNotAllow 855891 Microsoft Corporation Tax Books Application Suite... ApplicationSuite False DoNotAllow 895570102 Microsoft Corporation Tax Engine Application Suit... ApplicationSuite False DoNotAllow 8957001 Microsoft Corporation ### EXAMPLE 8 ``` Get-D365Model -Name "*Application*" -Module "*Suite*" ``` Shows the list of models where the name fits the search "*Application*" and the module name fits the search "*Suite*". A result set example: ModelName Module IsBinary Customization Id Publisher --------- ------ -------- ------------- -- --------- ApplicationSuiteFormAdaptor ApplicationSuiteFormAdaptor False DoNotAllow 855028 Microsoft Corporation AtlApplicationSuite AtlApplicationSuite False DoNotAllow 895972466 Microsoft Corporation Electronic Reporting Applic... ApplicationSuite False DoNotAllow 855009 Microsoft Corporation Tax Books Application Suite... ApplicationSuite False DoNotAllow 895570102 Microsoft Corporation Tax Engine Application Suit... ApplicationSuite False DoNotAllow 8957001 Microsoft Corporation ## PARAMETERS ### -Name Name of the model that you are looking for Accepts wildcards for searching. E.g. -Name "Application*Adaptor" Default value is "*" which will search for all models ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -Module Name of the module that you want to list models from Accepts wildcards for searchinf. E.g. -Module "Application*Adaptor" Default value is "*" which will search across all modules ```yaml Type: String Parameter Sets: (All) Aliases: ModuleName Required: False Position: 2 Default value: * Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -CustomizableOnly Instructs the cmdlet to filter out all models that cannot be customized ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ExcludeMicrosoftModels Instructs the cmdlet to exclude all models that has Microsoft as the publisher from the output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ExcludeBinaryModels Instruct the cmdlet to exclude binary models from the output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Default path is the same as the AOS service "PackagesLocalDirectory" directory Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: PackagesLocalDirectory, Servicing, Model, Models, Module, Modules Author: Mötz Jensen (@Splaxi) Author: Martin Dráb (@goshoom) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. ## RELATED LINKS ================================================ FILE: docs/Get-D365Module.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365Module ## SYNOPSIS Get installed package / module from Dynamics 365 Finance & Operations environment ## SYNTAX ``` Get-D365Module [[-Name] ] [-ExcludeBinaryModules] [-InDependencyOrder] [[-BinDir] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Get installed package / module from the machine running the AOS service for Dynamics 365 Finance & Operations ## EXAMPLES ### EXAMPLE 1 ``` Get-D365Module ``` Shows the entire list of installed packages / modules located in the default location on the machine. A result set example: ModuleName IsBinary Version References ---------- -------- ------- ---------- AccountsPayableMobile False 10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli... ApplicationCommon False 10.0.8008.26462 {ApplicationFoundation, ApplicationPlatform} ApplicationFoundation False 7.0.5493.35504 {ApplicationPlatform} ApplicationFoundationFormAdaptor False 7.0.4841.35227 {ApplicationPlatform, ApplicationFoundation, TestE... Custom True 10.0.0.0 {ApplicationPlatform} ### EXAMPLE 2 ``` Get-D365Module -ExcludeBinaryModules ``` Outputs the all packages / modules that are NOT binary. Will only include modules that is IsBinary = "False". A result set example: ModuleName IsBinary Version References ---------- -------- ------- ---------- AccountsPayableMobile False 10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli... ApplicationCommon False 10.0.8008.26462 {ApplicationFoundation, ApplicationPlatform} ApplicationFoundation False 7.0.5493.35504 {ApplicationPlatform} ApplicationFoundationFormAdaptor False 7.0.4841.35227 {ApplicationPlatform, ApplicationFoundation, TestE... ### EXAMPLE 3 ``` Get-D365Module -InDependencyOrder ``` Return packages / modules in dependency order, starting with modules with no references to other modules. A result set example: ModuleName IsBinary Version References ---------- -------- ------- ---------- ApplicationPlatform False 7.0.0.0 {} ApplicationFoundation False 7.0.0.0 {ApplicationPlatform} ApplicationCommon False 10.21.36.8818 {ApplicationFoundation, ApplicationPlatform} AppTroubleshootingCore False 10.21.1136.2... {ApplicationCommon, ApplicationFoundation, Applica... ### EXAMPLE 4 ``` Get-D365Module -Name "Application*Adaptor" ``` Shows the list of installed packages / modules where the name fits the search "Application*Adaptor". A result set example: ModuleName IsBinary Version References ---------- -------- ------- ---------- ApplicationFoundationFormAdaptor False 7.0.4841.35227 {ApplicationPlatform, ApplicationFoundation, TestE... ApplicationPlatformFormAdaptor False 7.0.4841.35227 {ApplicationPlatform, TestEssentials} ApplicationSuiteFormAdaptor False 10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli... ApplicationWorkspacesFormAdaptor False 10.0.9107.14827 {ApplicationFoundation, ApplicationPlatform, Appli... ## PARAMETERS ### -Name Name of the package / module that you are looking for Accepts wildcards for searching. E.g. -Name "Application*Adaptor" Default value is "*" which will search for all packages / modules ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -ExcludeBinaryModules Instruct the cmdlet to exclude binary modules from the output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -InDependencyOrder Instructs the cmdlet to return modules in dependency order, starting with modules with no references to other modules. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Dependency Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: PackagesLocalDirectory, Servicing, Model, Models, Package, Packages Author: Mötz Jensen (@Splaxi) Author: Martin Dráb (@goshoom) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. ## RELATED LINKS ================================================ FILE: docs/Get-D365OfflineAuthenticationAdminEmail.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365OfflineAuthenticationAdminEmail ## SYNOPSIS Gets the registered offline administrator e-mail configured ## SYNTAX ``` Get-D365OfflineAuthenticationAdminEmail [] ``` ## DESCRIPTION Get the registered offline administrator from the "DynamicsDevConfig.xml" file located in the default Package Directory ## EXAMPLES ### EXAMPLE 1 ``` Get-D365OfflineAuthenticationAdminEmail ``` Will read the DynamicsDevConfig.xml and display the registered Offline Administrator E-mail address. ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Development, Email, DynamicsDevConfig, Offline, Authentication This cmdlet is inspired by the work of "Sheikh Sohail Hussain" (twitter: @SSohailHussain) His blog can be found here: http://d365technext.blogspot.com The specific blog post that we based this cmdlet on can be found here: http://d365technext.blogspot.com/2018/07/offline-authentication-admin-email.html ## RELATED LINKS ================================================ FILE: docs/Get-D365PackageBundleDetail.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365PackageBundleDetail ## SYNOPSIS Get the details from an axscdppkg file ## SYNTAX ``` Get-D365PackageBundleDetail [-Path] [[-ExtractionPath] ] [[-KB] ] [[-Hotfix] ] [-Traverse] [-KeepFiles] [-IncludeRawManifest] [] ``` ## DESCRIPTION Get the details from an axscdppkg file by extracting it like a zip file. Capable of extracting the manifest details from the inner packages as well ## EXAMPLES ### EXAMPLE 1 ``` Get-D365PackageBundleDetail -Path "c:\temp\HotfixPackageBundle.axscdppkg" -Traverse ``` 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. ### EXAMPLE 2 ``` Get-D365PackageBundleDetail -Path "c:\temp\HotfixPackageBundle.axscdppkg" -ExtractionPath C:\Temp\20180905 -Traverse -KeepFiles ``` 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. ### EXAMPLE 3 ``` Get-D365PackageBundleDetail -Path C:\temp\HotfixPackageBundle.axscdppkg -Traverse -IncludeRawManifest ``` This is an advanced scenario. This will traverse the "HotfixPackageBundle.axscdppkg" file and will include the raw manifest file details in the output. ### EXAMPLE 4 ``` Get-D365PackageBundleDetail -Path C:\temp\HotfixPackageBundle.axscdppkg -Traverse -IncludeRawManifest | ForEach-Object {$_.RawManifest | Out-File "C:\temp\$($_.PackageId).txt"} ``` This is an advanced scenario. This will traverse the "HotfixPackageBundle.axscdppkg" file and save the manifest files into c:\temp. Everything else is omitted and cleaned up. ## PARAMETERS ### -Path Path to the axscdppkg file you want to analyze ```yaml Type: String Parameter Sets: (All) Aliases: File Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ExtractionPath Path where you want the cmdlet to work with extraction of all the files Default value is: C:\Users\Username\AppData\Local\Temp ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: ([System.IO.Path]::GetTempPath()) Accept pipeline input: False Accept wildcard characters: False ``` ### -KB KB number of the hotfix that you are looking for Accepts wildcards for searching. E.g. -KB "4045*" Default value is "*" which will search for all KB's ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -Hotfix Package Id / Hotfix number the hotfix that you are looking for Accepts wildcards for searching. E.g. -Hotfix "7045*" Default value is "*" which will search for all hotfixes ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -Traverse Switch to instruct the cmdlet to traverse the inner packages and extract their details ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -KeepFiles Switch to instruct the cmdlet to keep the files for further manual analyze ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -IncludeRawManifest Switch to instruct the cmdlet to include the raw content of the manifest file Only works with the -Traverse option ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Hotfix, KB, Manifest, HotfixPackageBundle, axscdppkg, Package, Bundle, Deployable Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365PackageLabelResourceFile.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365PackageLabelResourceFile ## SYNOPSIS Get label / resource file from a package ## SYNTAX ### Default (Default) ``` Get-D365PackageLabelResourceFile -PackageDirectory [-Name ] [-Language ] [] ``` ### Specific ``` Get-D365PackageLabelResourceFile -PackageDirectory [-Name ] [-Language ] [] ``` ## DESCRIPTION Get label (resource) file from the package directory of a Dynamics 365 Finance & Operations environment ## EXAMPLES ### EXAMPLE 1 ``` Get-D365PackageLabelResourceFile -PackageDirectory "C:\AOSService\PackagesLocalDirectory\ApplicationSuite" ``` Shows all the label files for ApplicationSuite package ### EXAMPLE 2 ``` Get-D365PackageLabelResourceFile -PackageDirectory "C:\AOSService\PackagesLocalDirectory\ApplicationSuite" -Name "Fixed*Accounting" ``` Shows the label files for ApplicationSuite package where the name fits the search "Fixed*Accounting" ### EXAMPLE 3 ``` Get-D365InstalledPackage -Name "ApplicationSuite" | Get-D365PackageLabelResourceFile ``` Shows all label files (en-US) for the ApplicationSuite package ## PARAMETERS ### -PackageDirectory Path to the directory containing the installed packages Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: Default Aliases: Path Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: Specific Aliases: Path Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Name Name of the label (resource) file you are looking for Accepts wildcards for searching. E.g. -Name "Fixed*Accounting" Default value is "*" which will search for all label files ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -Language The language of the label file you are looking for Accepts wildcards for searching. E.g. -Language "en*" Default value is "en-US" which will search for en-US language files ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: En-US Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: PackagesLocalDirectory, Label, Labels, Language, Development, Servicing, Module, Package, Packages Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. ## RELATED LINKS ================================================ FILE: docs/Get-D365PackageLabelResources.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365PackageLabelResources ## SYNOPSIS Get label from the resource file ## SYNTAX ### Default (Default) ``` Get-D365PackageLabelResources -FilePath [-Name ] [-Value ] [-IncludePath] [] ``` ### Specific ``` Get-D365PackageLabelResources -FilePath [-Name ] [-Value ] [-IncludePath] [] ``` ## DESCRIPTION Get label details from the resource file for a Dynamics 365 Finance & Operations environment ## EXAMPLES ### EXAMPLE 1 ``` Get-D365PackageLabelResources -Path "C:\AOSService\PackagesLocalDirectory\ApplicationSuite\Resources\en-US\PRO.resources.dll" ``` Will get all labels from the "PRO.resouce.dll" file The language is determined by the path to the resource file and nothing else ### EXAMPLE 2 ``` Get-D365PackageLabelResources -Path "C:\AOSService\PackagesLocalDirectory\ApplicationSuite\Resources\en-US\PRO.resources.dll" -Name "@PRO505" ``` Will get the label with the name "@PRO505" from the "PRO.resouce.dll" file The language is determined by the path to the resource file and nothing else ### EXAMPLE 3 ``` Get-D365PackageLabelResources -Path "C:\AOSService\PackagesLocalDirectory\ApplicationSuite\Resources\en-US\PRO.resources.dll" -Value "*qty*" ``` Will get all the labels where the value fits the search "*qty*" from the "PRO.resouce.dll" file The language is determined by the path to the resource file and nothing else ### EXAMPLE 4 ``` Get-D365InstalledPackage -Name "ApplicationSuite" | Get-D365PackageLabelResourceFile -Language "da" | Get-D365PackageLabelResources -value "*batch*" -IncludePath ``` 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*". The path to the label file is included in the output. ## PARAMETERS ### -FilePath The path to resource file that you want to get label details from ```yaml Type: String Parameter Sets: Default Aliases: Path Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: Specific Aliases: Path Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Name Name of the label you are looking for Accepts wildcards for searching. E.g. -Name "@PRO*" Default value is "*" which will search for all labels in the resource file ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -Value Value of the label you are looking for Accepts wildcards for searching. E.g. -Name "*Qty*" Default value is "*" which will search for all values in the resource file ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -IncludePath Switch to indicate whether you want the result set to include the path to the resource file or not Default is OFF - path details will not be part of the output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: PackagesLocalDirectory, Label, Labels, Language, Development, Servicing, Resource, Resources Author: Mötz Jensen (@Splaxi) There are several advanced scenarios for this cmdlet. See more on github and the wiki pages. ## RELATED LINKS ================================================ FILE: docs/Get-D365ProductInformation.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365ProductInformation ## SYNOPSIS Returns information about D365FO ## SYNTAX ``` Get-D365ProductInformation [] ``` ## DESCRIPTION Gets detailed information about application and platform ## EXAMPLES ### EXAMPLE 1 ``` Get-D365ProductInformation ``` This will get product, platform and application version details for the environment ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Build, Version, Reference, ProductVersion, ProductDetails, Product Author: Rasmus Andersen (@ITRasmus) The cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations. The call to the dll file gets all relevant product details for the environment. ## RELATED LINKS ================================================ FILE: docs/Get-D365RsatCertificateThumbprint.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365RsatCertificateThumbprint ## SYNOPSIS Get the thumbprint from the RSAT certificate ## SYNTAX ``` Get-D365RsatCertificateThumbprint [] ``` ## DESCRIPTION Locate the thumbprint for the certificate created during the RSAT installation ## EXAMPLES ### EXAMPLE 1 ``` Get-D365RsatCertificateThumbprint ``` This will locate any certificates that has 127.0.0.1 in its name. It will show the subject and the thumbprint values. ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: RSAT, Certificate, Testing, Regression Suite Automation Test, Regression, Test, Automation. Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365RsatPlaybackFile.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365RsatPlaybackFile ## SYNOPSIS Get the RSAT playback files ## SYNTAX ### Default (Default) ``` Get-D365RsatPlaybackFile [-Path ] [-Name ] [] ``` ### ExecutionUser ``` Get-D365RsatPlaybackFile [-Name ] [-ExecutionUsername ] [] ``` ## DESCRIPTION Get all the RSAT playback files from the last executions ## EXAMPLES ### EXAMPLE 1 ``` Get-D365RsatPlaybackFile ``` This will get all the RSAT playback files. It will search for the files in the current user AppData system folder. ### EXAMPLE 2 ``` Get-D365RsatPlaybackFile -Name *4080* ``` This will get all the RSAT playback files which has "4080" as part of its name. It will search for the files in the current user AppData system folder. ### EXAMPLE 3 ``` Get-D365RsatPlaybackFile -ExecutionUsername RSAT-ServiceAccount ``` This will get all the RSAT playback files that were executed by the RSAT-ServiceAccount user. It will search for the files in the RSAT-ServiceAccount user AppData system folder. ## PARAMETERS ### -Path The path where the RSAT tool will be writing the files The default path is: "C:\Users\USERNAME\AppData\Roaming\regressionTool\playback" ```yaml Type: String Parameter Sets: Default Aliases: Required: False Position: Named Default value: $Script:RsatplaybackPath Accept pipeline input: False Accept wildcard characters: False ``` ### -Name Name of Test Case that you are looking for Default value is "*" which will search for all Test Cases and their corresponding files ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -ExecutionUsername Name of the user account has been running the RSAT tests on a machine that isn't the same as the current user 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 ```yaml Type: String Parameter Sets: ExecutionUser Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, Playback Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365RsatSoapHostname.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365RsatSoapHostname ## SYNOPSIS Get the SOAP hostname for the D365FO environment ## SYNTAX ``` Get-D365RsatSoapHostname [] ``` ## DESCRIPTION Get the SOAP hostname from the IIS configuration, to be used during the Rsat configuration ## EXAMPLES ### EXAMPLE 1 ``` Get-D365RsatSoapHostname ``` This will get the SOAP hostname from IIS. It will display the SOAP URL / URI correctly formatted, to be used during the configuration of Rsat. ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, SOAP Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365Runbook.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365Runbook ## SYNOPSIS Get a Dynamics 365 Runbook ## SYNTAX ``` Get-D365Runbook [[-Path] ] [[-Name] ] [-Latest] [] ``` ## DESCRIPTION Get the full path and filename of a Dynamics 365 Runbook ## EXAMPLES ### EXAMPLE 1 ``` Get-D365Runbook ``` This will list all runbooks that are available in the default location. ### EXAMPLE 2 ``` Get-D365Runbook -Latest ``` This will get the latest runbook file from the default InstallationRecords directory on the machine. ### EXAMPLE 3 ``` Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer ``` This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. ### EXAMPLE 4 ``` Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer | Out-File "C:\Temp\d365fo.tools\runbook-analyze-results.xml" ``` This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. The output will be saved into the "C:\Temp\d365fo.tools\runbook-analyze-results.xml" file. ### EXAMPLE 5 ``` Get-D365Runbook | Backup-D365Runbook ``` This will save a copy of all runbooks from the default location and save them to "c:\temp\d365fo.tools\runbookbackups" ### EXAMPLE 6 ``` notepad.exe (Get-D365Runbook -Latest).File ``` This will find the latest runbook file and open it with notepad. ## PARAMETERS ### -Path Path to the folder containing the runbook files The default path is "InstallationRecord" which is normally located on the "C:\DynamicsAX\InstallationRecords" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: (Join-Path $Script:InstallationRecordsDir "Runbooks") Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -Name Name of the runbook file that you are looking for The parameter accepts wildcards. E.g. -Name *hotfix-20181024* ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -Latest Instruct the cmdlet to only get the latest runbook file, based on the last written attribute ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Runbook, Servicing, Hotfix, DeployablePackage, Deployable Package, InstallationRecordsDirectory, Installation Records Directory Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365RunbookId.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365RunbookId ## SYNOPSIS Get runbook id ## SYNTAX ``` Get-D365RunbookId [-Path] [] ``` ## DESCRIPTION Get the runbook id from inside a runbook file ## EXAMPLES ### EXAMPLE 1 ``` Get-D365RunbookId -Path "C:\DynamicsAX\InstallationRecords\Runbooks\Runbook.xml" ``` This will inspect the Runbook.xml file and output the runbookid from inside the XML document. ### EXAMPLE 2 ``` Get-D365Runbook | Get-D365RunbookId ``` This will find all runbook file(s) and have them analyzed by the Get-D365RunbookId cmdlet to output the runbookid(s). ### EXAMPLE 3 ``` Get-D365Runbook -Latest | Get-D365RunbookId ``` This will find the latest runbook file and have it analyzed by the Get-D365RunbookId cmdlet to output the runbookid. ## PARAMETERS ### -Path Path to the runbook file that you want to analyse Accepts value from pipeline, also by property ```yaml Type: String Parameter Sets: (All) Aliases: File Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Runbook, Analyze, RunbookId, Runbooks Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365RunbookLogFile.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365RunbookLogFile ## SYNOPSIS Get log file from a Runbook step ## SYNTAX ``` Get-D365RunbookLogFile [-Path] [-Step] [-Latest] [-OpenInEditor] [] ``` ## DESCRIPTION Get the log files for a specific Runbook step ## EXAMPLES ### EXAMPLE 1 ``` Get-D365RunbookLogFile -Path "C:\Temp\PU35" -Step 34 ``` This will locate all logfiles that has been outputted from the Step 34 from the PU35 installation. The output will list the complete path to the log files. An output example: Filename : AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log LastModified : 8/7/2020 12:40:34 PM File : C:\Temp\PU35\RunbookWorkingFolder\Runbook\MININT-F36S5EH\DIXFService\34\Log\AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log Filename : AutoUpdateDIXFService.ps1-2020-07-8--12-36-22.log LastModified : 8/7/2020 12:36:22 PM File : C:\Temp\PU35\RunbookWorkingFolder\Runbook\MININT-F36S5EH\DIXFService\34\Log\AutoUpdateDIXFService.ps1-2020-07-8--12-36-22.log Filename : AutoUpdateDIXFService.ps1-2020-05-8--19-15-07.log LastModified : 8/5/2020 7:15:07 PM File : C:\Temp\PU35\RunbookWorkingFolder\Runbook\MININT-F36S5EH\DIXFService\34\Log\AutoUpdateDIXFService.ps1-2020-05-8--19-15-07.log ### EXAMPLE 2 ``` Get-D365RunbookLogFile -Path "C:\Temp\PU35" -Step 34 -Latest ``` This will locate all logfiles that has been outputted from the Step 34 from the PU35 installation. The output will be limited to the latest log, based on last write time. The output will list the complete path to the log file. An output example: Filename : AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log LastModified : 8/7/2020 12:40:34 PM File : C:\Temp\PU35\RunbookWorkingFolder\Runbook\MININT-F36S5EH\DIXFService\34\Log\AutoUpdateDIXFService.ps1-2020-07-8--12-40-34.log ### EXAMPLE 3 ``` Get-D365RunbookLogFile -Path "C:\Temp\PU35" -Step 34 -OpenInEditor ``` This will locate all logfiles that has been outputted from the Step 34 from the PU35 installation. The Get-D365RunbookLogFile will open all log files in the default text editor. ### EXAMPLE 4 ``` Get-D365RunbookLogFile -Path "C:\Temp\PU35" -Step 34 -Latest -OpenInEditor ``` This will locate all logfiles that has been outputted from the Step 34 from the PU35 installation. The output will be limited to the latest log, based on last write time. The Get-D365RunbookLogFile will open the log file in the default text editor. ### EXAMPLE 5 ``` Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnlyAsObjects | Get-D365RunbookLogFile -Path "C:\Temp\PU35" -OpenInEditor ``` This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. The output from Invoke-D365RunbookAnalyzer will only contain failed steps. The Get-D365RunbookLogFile will open all log files for the failed step. ## PARAMETERS ### -Path Path to Software Deployable Package that was run in connection with the runbook ```yaml Type: String Parameter Sets: (All) Aliases: File Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -Step Step id for the step that you want to locate the log files for ```yaml Type: String Parameter Sets: (All) Aliases: StepId Required: True Position: 2 Default value: None Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -Latest Instruct the cmdlet to only work with the latest log file Is based on the last written attribute on the log file ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OpenInEditor Instruct the cmdlet to open the log file in the default text editor ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### System.String ## NOTES Tags: Runbook, Servicing, Hotfix, DeployablePackage, Deployable Package, InstallationRecordsDirectory, Installation Records Directory Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365SDPCleanUp.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365SDPCleanUp ## SYNOPSIS Get the cleanup retention period ## SYNTAX ``` Get-D365SDPCleanUp [] ``` ## DESCRIPTION Gets the configured retention period before updates are deleted ## EXAMPLES ### EXAMPLE 1 ``` Get-D365SDPCleanUp ``` This will get the configured retention period from the registry ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: CleanUp, Retention, Servicing, Cut Off, DeployablePackage, Deployable Package Author: Mötz Jensen (@Splaxi) This cmdlet is based on the findings from Alex Kwitny (@AlexOnDAX) See his blog for more info: http://www.alexondax.com/2018/04/msdyn365fo-how-to-adjust-your.html ## RELATED LINKS ================================================ FILE: docs/Get-D365SDPDetails.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365SDPDetails ## SYNOPSIS Get details from the Software Deployable Package ## SYNTAX ``` Get-D365SDPDetails [-Path] [] ``` ## DESCRIPTION Details details about the inner modules / packages that a Software Deployable Contains ## EXAMPLES ### EXAMPLE 1 ``` Get-D365SDPDetails -Path 'C:\Temp\RV-10.0.36.44.zip' ``` This will display the basic details about the package. The package is a zip file. A result set example: Platform PlatformVersion Modules -------- --------------- ------- Update55 7.0.6651.92 {@{Name=RapidValue; Version=7.0.6651.92}, @{Name=TCLCommon; Version=7.0.6651.92}, @{Name=TC... ### EXAMPLE 2 ``` Get-D365SDPDetails -Path 'C:\Temp\RV-10.0.36.44' ``` This will display the basic details about the package. The package is extracted to a local folder. A result set example: Platform PlatformVersion Modules -------- --------------- ------- Update55 7.0.6651.92 {@{Name=RapidValue; Version=7.0.6651.92}, @{Name=TCLCommon; Version=7.0.6651.92}, @{Name=TC... ### EXAMPLE 3 ``` Get-D365SDPDetails -Path 'C:\Temp\RV-10.0.36.44.zip' | Select-Object -ExpandProperty Modules ``` This will display the module details that are part of the package. The package is a zip file. A result set example: Name Version ---- ------- RapidValue 7.0.6651.92 TCLCommon 7.0.6651.92 TCLLabel 7.0.6651.92 ## PARAMETERS ### -Path Path to the Software Deployable Package that you want to work against The cmdlet supports a path to a zip-file or directory with the unpacked content ```yaml Type: String Parameter Sets: (All) Aliases: File Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365Table.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365Table ## SYNOPSIS Get a table ## SYNTAX ### Default (Default) ``` Get-D365Table [[-Name] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [] ``` ### TableId ``` Get-D365Table [-Id] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [] ``` ## DESCRIPTION Get a table either by TableName (wildcard search allowed) or by TableId ## EXAMPLES ### EXAMPLE 1 ``` Get-D365Table -Name CustTable ``` Will get the details for the CustTable ### EXAMPLE 2 ``` Get-D365Table -Id 10347 ``` Will get the details for the table with the id 10347. ## PARAMETERS ### -Name Name of the table that you are looking for Accepts wildcards for searching. E.g. -Name "Cust*" Default value is "*" which will search for all tables ```yaml Type: String[] Parameter Sets: Default Aliases: Required: False Position: 2 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -Id The specific id for the table you are looking for ```yaml Type: Int32 Parameter Sets: TableId Aliases: Required: True Position: 2 Default value: 0 Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Table, Tables, AOT, TableId, Development Author: Mötz Jensen (@splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. ## RELATED LINKS ================================================ FILE: docs/Get-D365TableField.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365TableField ## SYNOPSIS Get a field from table ## SYNTAX ### Default (Default) ``` Get-D365TableField [-TableId] [[-Name] ] [[-FieldId] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [-IncludeTableDetails] [] ``` ### SearchByNameForce ``` Get-D365TableField [[-Name] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [-SearchAcrossTables] [] ``` ### TableName ``` Get-D365TableField [[-Name] ] [[-FieldId] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [-TableName] [-IncludeTableDetails] [] ``` ## DESCRIPTION Get a field either by FieldName (wildcard search allowed) or by FieldId ## EXAMPLES ### EXAMPLE 1 ``` Get-D365TableField -TableId 10347 ``` Will get all field details for the table with id 10347. ### EXAMPLE 2 ``` Get-D365TableField -TableName CustTable ``` Will get all field details for the CustTable table. ### EXAMPLE 3 ``` Get-D365TableField -TableId 10347 -FieldId 175 ``` Will get the details for the field with id 175 that belongs to the table with id 10347. ### EXAMPLE 4 ``` Get-D365TableField -TableId 10347 -Name "VATNUM" ``` Will get the details for the "VATNUM" that belongs to the table with id 10347. ### EXAMPLE 5 ``` Get-D365TableField -TableId 10347 -Name "VAT*" ``` Will get the details for all fields that fits the search "VAT*" that belongs to the table with id 10347. ### EXAMPLE 6 ``` Get-D365TableField -Name AccountNum -SearchAcrossTables ``` Will search for the AccountNum field across all tables. ### EXAMPLE 7 ``` Get-D365TableField -TableName CustTable -IncludeTableDetails ``` Will get all field details for the CustTable table. Will include table details in the output. ## PARAMETERS ### -TableId The id of the table that the field belongs to ```yaml Type: Int32 Parameter Sets: Default Aliases: Required: True Position: 2 Default value: 0 Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Name Name of the field that you are looking for Accepts wildcards for searching. E.g. -Name "Account*" Default value is "*" which will search for all fields ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -FieldId Id of the field that you are looking for Type is integer ```yaml Type: Int32 Parameter Sets: Default, TableName Aliases: Required: False Position: 4 Default value: 0 Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 8 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -TableName Name of the table that the field belongs to Search will only return the first hit (unordered) and work against that hit ```yaml Type: String Parameter Sets: TableName Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -IncludeTableDetails Switch options to enable the result set to include extended details ```yaml Type: SwitchParameter Parameter Sets: Default, TableName Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -SearchAcrossTables Switch options to force the cmdlet to search across all tables when looking for the field ```yaml Type: SwitchParameter Parameter Sets: SearchByNameForce Aliases: Required: True Position: 3 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Table, Tables, Fields, TableField, Table Field, TableName, TableId Author: Mötz Jensen (@splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. ## RELATED LINKS ================================================ FILE: docs/Get-D365TableSequence.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365TableSequence ## SYNOPSIS Get the sequence object for table ## SYNTAX ``` Get-D365TableSequence [[-TableName] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [] ``` ## DESCRIPTION Get the sequence details for tables ## EXAMPLES ### EXAMPLE 1 ``` Get-D365TableSequence | Format-Table ``` This will get all the sequence details for all tables inside the database. It will format the output as a table for better overview. ### EXAMPLE 2 ``` Get-D365TableSequence -TableName "Custtable" | Format-Table ``` This will get the sequence details for the CustTable in the database. It will format the output as a table for better overview. ### EXAMPLE 3 ``` Get-D365TableSequence -TableName "Cust*" | Format-Table ``` This will get the sequence details for all tables that matches the search "Cust*" in the database. It will format the output as a table for better overview. ### EXAMPLE 4 ``` Get-D365Table -Name CustTable | Get-D365TableSequence | Format-Table ``` This will get the table details from the Get-D365Table cmdlet and pipe that into Get-D365TableSequence. This will get the sequence details for the CustTable in the database. It will format the output as a table for better overview. ## PARAMETERS ### -TableName Name of the table that you want to work against Accepts wildcards for searching. E.g. -TableName "Cust*" Default value is "*" which will search for all tables ```yaml Type: String Parameter Sets: (All) Aliases: Name Required: False Position: 2 Default value: * Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Table, RecId, Sequence, Record Id Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365TablesInChangedTracking.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365TablesInChangedTracking ## SYNOPSIS Get table that is taking part of Change Tracking ## SYNTAX ``` Get-D365TablesInChangedTracking [[-Name] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [] ``` ## DESCRIPTION Get table(s) that is taking part of the SQL Server Change Tracking mechanism ## EXAMPLES ### EXAMPLE 1 ``` Get-D365TablesInChangedTracking ``` This will list all tables that are taking part in the SQL Server Change Tracking. ### EXAMPLE 2 ``` Get-D365TablesInChangedTracking -Name CustTable ``` This will search for a table in the list of tables that are taking part in the SQL Server Change Tracking. It will use the CustTable as the search pattern while searching for the table. ## PARAMETERS ### -Name Name of the table that you are looking for Accepts wildcards for searching. E.g. -Name "Cust*" Default value is "*" which will search for all tables ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Table, Change Tracking, Tablename, DMF, DIXF Author: Mötz Jensen (@splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365TfsUri.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365TfsUri ## SYNOPSIS Get the TFS / VSTS registered URL / URI ## SYNTAX ``` Get-D365TfsUri [[-Path] ] [] ``` ## DESCRIPTION Gets the URI from the configuration of the local tfs connection in visual studio ## EXAMPLES ### EXAMPLE 1 ``` Get-D365TfsUri ``` This will invoke the default tf.exe client located in the Visual Studio 2015 directory and fetch the configured URI. ## PARAMETERS ### -Path Path to the tf.exe file that the cmdlet will invoke ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:TfDir Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: TFS, VSTS, URL, URI, Servicing, Development Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365TfsWorkspace.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365TfsWorkspace ## SYNOPSIS Get the TFS / VSTS registered workspace path ## SYNTAX ``` Get-D365TfsWorkspace [[-Path] ] [[-TfsUri] ] [] ``` ## DESCRIPTION Gets the workspace path from the configuration of the local tfs in visual studio ## EXAMPLES ### EXAMPLE 1 ``` Get-D365TfsWorkspace -TfsUri https://PROJECT.visualstudio.com ``` This will invoke the default tf.exe client located in the Visual Studio 2015 directory and fetch the configured URI. ## PARAMETERS ### -Path Path to the directory where the Team Foundation Client executable is located ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:TfDir Accept pipeline input: False Accept wildcard characters: False ``` ### -TfsUri Uri to the TFS / VSTS that the workspace is connected to ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:TfsUri Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: TFS, VSTS, URL, URI, Servicing, Development Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365Url.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365Url ## SYNOPSIS Get the url for accessing the instance ## SYNTAX ``` Get-D365Url [-Force] [] ``` ## DESCRIPTION Get the complete URL for accessing the Dynamics 365 Finance & Operations instance running on this machine ## EXAMPLES ### EXAMPLE 1 ``` Get-D365Url ``` This will get the correct URL to access the environment ## PARAMETERS ### -Force Switch to instruct the cmdlet to retrieve the name from the system files instead of the name stored in memory after loading this module. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: URL, URI, Servicing Author: Rasmus Andersen (@ITRasmus) The cmdlet wraps the call against a dll file that is shipped with Dynamics 365 for Finance & Operations. The call to the dll file gets all registered URL for the environment. ## RELATED LINKS ================================================ FILE: docs/Get-D365User.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365User ## SYNOPSIS Get users from the environment ## SYNTAX ``` Get-D365User [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-Email] ] [-ExcludeSystemUsers] [] ``` ## DESCRIPTION Get all relevant user details from the Dynamics 365 for Finance & Operations ## EXAMPLES ### EXAMPLE 1 ``` Get-D365User ``` This will get all users from the environment. ### EXAMPLE 2 ``` Get-D365User -ExcludeSystemUsers ``` This will get all users from the environment, but filter out all known system user accounts. ### EXAMPLE 3 ``` Get-D365User -Email "*contoso.com" ``` This will search for all users with an e-mail address containing 'contoso.com' from the environment. ## PARAMETERS ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -Email The search string to select which user(s) should be updated The parameter supports wildcards. E.g. -Email "*@contoso.com*" Default value is "*" to get all users ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -ExcludeSystemUsers Instructs the cmdlet to filter out all known system users ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: User, Users Author: Mötz Jensen (@Splaxi) Author: Rasmus Andersen (@ITRasmus) ## RELATED LINKS ================================================ FILE: docs/Get-D365UserAuthenticationDetail.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365UserAuthenticationDetail ## SYNOPSIS Cmdlet used to get authentication details about a user ## SYNTAX ``` Get-D365UserAuthenticationDetail [-Email] [] ``` ## 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 & Operations ## EXAMPLES ### EXAMPLE 1 ``` Get-D365UserAuthenticationDetail -Email "Claire@contoso.com" ``` This will get all the authentication details for the user account with the email address "Claire@contoso.com" ## PARAMETERS ### -Email The e-mail address / login name of the user that the cmdlet must gather details about ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: True (ByValue) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: User, Users, Security, Configuration, Authentication Author : Rasmus Andersen (@ITRasmus) Author : Mötz Jensen (@splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365VisualStudioCompilerResult.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365VisualStudioCompilerResult ## SYNOPSIS Get the compiler outputs presented ## SYNTAX ``` Get-D365VisualStudioCompilerResult [[-Module] ] [-ErrorsOnly] [-OutputTotals] [-OutputAsObjects] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Get the Visual Studio compiler outputs presented in a structured manner on the screen ## EXAMPLES ### EXAMPLE 1 ``` Get-D365VisualStudioCompilerResult ``` This will return the compiler output for all modules. A result set example: File Warnings Errors ---- -------- ------ K:\AosService\PackagesLocalDirectory\ApplicationCommon\BuildModelResult.log 55 0 K:\AosService\PackagesLocalDirectory\ApplicationFoundation\BuildModelResult.log 692 0 K:\AosService\PackagesLocalDirectory\ApplicationPlatform\BuildModelResult.log 155 0 K:\AosService\PackagesLocalDirectory\ApplicationSuite\BuildModelResult.log 10916 0 K:\AosService\PackagesLocalDirectory\CustomModule\BuildModelResult.log 1 2 ### EXAMPLE 2 ``` Get-D365VisualStudioCompilerResult -ErrorsOnly ``` This will return the compiler output for all modules where there was errors in. A result set example: File Warnings Errors ---- -------- ------ K:\AosService\PackagesLocalDirectory\CustomModule\BuildModelResult.log 1 2 ### EXAMPLE 3 ``` Get-D365VisualStudioCompilerResult -ErrorsOnly -OutputAsObjects ``` This will return the compiler output for all modules where there was errors in. The output will be PSObjects, which can be assigned to a variable and used for futher analysis. A result set example: File Warnings Errors ---- -------- ------ K:\AosService\PackagesLocalDirectory\CustomModule\BuildModelResult.log 1 2 ### EXAMPLE 4 ``` Get-D365VisualStudioCompilerResult -OutputTotals ``` This will return the compiler output for all modules and write a total overview to the console. A result set example: File Warnings Errors ---- -------- ------ K:\AosService\PackagesLocalDirectory\ApplicationCommon\BuildModelResult.log 55 0 K:\AosService\PackagesLocalDirectory\ApplicationFoundation\BuildModelResult.log 692 0 K:\AosService\PackagesLocalDirectory\ApplicationPlatform\BuildModelResult.log 155 0 K:\AosService\PackagesLocalDirectory\ApplicationSuite\BuildModelResult.log 10916 0 K:\AosService\PackagesLocalDirectory\CustomModule\BuildModelResult.log 1 2 Total Errors: 2 Total Warnings: 11819 ## PARAMETERS ### -Module Name of the module that you want to work against Default value is "*" which will search for all modules ```yaml Type: String Parameter Sets: (All) Aliases: ModuleName Required: False Position: 1 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -ErrorsOnly Instructs the cmdlet to only output compile results where there was errors detected ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputTotals Instructs the cmdlet to output the total errors and warnings after the analysis ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputAsObjects Instructs the cmdlet to output the objects instead of formatting them 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 ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Default path is the same as the AOS service "PackagesLocalDirectory" directory Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### [PsCustomObject] ## NOTES Tags: Compiler, Build, Errors, Warnings, Tasks Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Vilmos Kintera" (twitter: @DAXRunBase) All credits goes to him for showing how to extract these information His blog can be found here: https://www.daxrunbase.com/blog/ The specific blog post that we based this cmdlet on can be found here: https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/ The github repository containing the original scrips can be found here: https://github.com/DAXRunBase/PowerShell-and-Azure ## RELATED LINKS ================================================ FILE: docs/Get-D365WebServerType.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365WebServerType ## SYNOPSIS Get the default web server to be used ## SYNTAX ``` Get-D365WebServerType [] ``` ## DESCRIPTION Get the web server which will be used to run D365FO: Either IIS or IIS Express. Newly deployed development machines will have this set to IIS Express by default. It will look for the file located in the default Package Directory. ## EXAMPLES ### EXAMPLE 1 ``` Get-D365WebServerType ``` This will display the current web server type registered in the "DynamicsDevConfig.xml" file. Located in "K:\AosService\PackagesLocalDirectory\bin". ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tag: Web Server, IIS, IIS Express, Development Author: Sander Holvoet (@smholvoet) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Get-D365WindowsActivationStatus.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Get-D365WindowsActivationStatus ## SYNOPSIS Get activation status ## SYNTAX ``` Get-D365WindowsActivationStatus [] ``` ## DESCRIPTION Get all the important license and activation information from the machine ## EXAMPLES ### EXAMPLE 1 ``` Get-D365WindowsActivationStatus ``` This will get the remaining grace and rearm activation information for the machine ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Windows, License, Activation, Arm, Rearm Author: Mötz Jensen (@Splaxi) The cmdlet uses CIM objects to access the activation details ## RELATED LINKS ================================================ FILE: docs/Import-D365AadApplication.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Import-D365AadApplication ## SYNOPSIS Used to import Aad applications into D365FO ## SYNTAX ``` Import-D365AadApplication [-Name] [-UserId] [-ClientId] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [] ``` ## DESCRIPTION Provides a method for importing a AAD application into D365FO. ## EXAMPLES ### EXAMPLE 1 ``` Import-D365AadApplication -Name "Application1" -UserId "admin" -ClientId "aef2e67c-64a3-4c72-9294-d288c5bf503d" ``` Imports Application1 as an application linked to user admin into the D365FO environment. ## PARAMETERS ### -Name The name that the imported application should have inside the D365FO environment ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -UserId The id of the user linked to the application inside the D365FO environment ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ClientId The Client ID that the imported application should use inside the D365FO environment ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: User, Users, Security, Configuration, Permission, AAD, Azure Active Directory, Group, Groups Author: Gert Van Der Heyden (@gertvdheyden) At no circumstances can this cmdlet be used to import users into a PROD environment. ## RELATED LINKS ================================================ FILE: docs/Import-D365AadUser.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Import-D365AadUser ## SYNOPSIS Used to import Aad users into D365FO ## SYNTAX ### UserListImport (Default) ``` Import-D365AadUser [-Users] [[-StartupCompany] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-IdPrefix] ] [[-NameSuffix] ] [[-IdValue] ] [[-NameValue] ] [[-AzureAdCredential] ] [-SkipAzureAd] [[-EmailValue] ] [[-TenantId] ] [] ``` ### GroupNameImport ``` Import-D365AadUser [-AadGroupName] [[-StartupCompany] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-IdPrefix] ] [[-NameSuffix] ] [[-IdValue] ] [[-NameValue] ] [[-AzureAdCredential] ] [-ForceExactAadGroupName] [[-EmailValue] ] [[-TenantId] ] [] ``` ### GroupIdImport ``` Import-D365AadUser [[-StartupCompany] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-IdPrefix] ] [[-NameSuffix] ] [[-IdValue] ] [[-NameValue] ] [[-AzureAdCredential] ] [-AadGroupId] [[-EmailValue] ] [[-TenantId] ] [] ``` ## DESCRIPTION Provides a method for importing a AAD UserGroup or a comma separated list of AadUsers into D365FO. ## EXAMPLES ### EXAMPLE 1 ``` Import-D365AadUser -Users "Claire@contoso.com","Allen@contoso.com" ``` Imports Claire and Allen as users ### EXAMPLE 2 ``` $myPassword = ConvertTo-SecureString "MyPasswordIsSecret" -AsPlainText -Force ``` PS C:\\\> $myCredentials = New-Object System.Management.Automation.PSCredential ("MyEmailIsAlso", $myPassword) PS C:\\\> Import-D365AadUser -Users "Claire@contoso.com","Allen@contoso.com" -AzureAdCredential $myCredentials This will import Claire and Allen as users. ### EXAMPLE 3 ``` Import-D365AadUser -AadGroupName "CustomerTeam1" ``` if more than one group match the AadGroupName, you can use the ExactAadGroupName parameter Import-D365AadUser -AadGroupName "CustomerTeam1" -ForceExactAadGroupName ### EXAMPLE 4 ``` Import-D365AadUser -AadGroupName "CustomerTeam1" -ForceExactAadGroupName ``` This is used to force the cmdlet to find the exact named group in Azure Active Directory. ### EXAMPLE 5 ``` Import-D365AadUser -AadGroupId "99999999-aaaa-bbbb-cccc-9999999999" ``` Imports all the users that is present in the AAD Group called CustomerTeam1 ### EXAMPLE 6 ``` Import-D365AadUser -Users "Claire@contoso.com","Allen@contoso.com" -SkipAzureAd ``` Imports Claire and Allen as users. Will NOT make you connect to the Azure Active Directory(AAD). The needed details will be based on the e-mail address only, and the rest will be blanked. ### EXAMPLE 7 ``` Import-D365AadUser -Users "Claire@contoso.com","Allen@contoso.com" -TenantId "99999999-aaaa-bbbb-cccc-9999999999" ``` Imports Claire and Allen as users. Uses tenant id "99999999-aaaa-bbbb-cccc-9999999999" when connecting to Azure Active Directory(AAD). ## PARAMETERS ### -AadGroupName Azure Active directory user group containing users to be imported ```yaml Type: String Parameter Sets: GroupNameImport Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Users Array of users that you want to import into the D365FO environment ```yaml Type: String[] Parameter Sets: UserListImport Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -StartupCompany Startup company of users imported. Default is DAT ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: DAT Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -IdPrefix A text that will be prefixed into the ID field. E.g. -IdPrefix "EXT-" will import users and set ID starting with "EXT-..." ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 8 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -NameSuffix A text that will be suffixed into the NAME field. E.g. -NameSuffix "(Contoso)" will import users and append "(Contoso)"" to the NAME ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 9 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -IdValue Specify which field to use as ID value when importing the users. Available options 'Login' / 'FirstName' / 'UserPrincipalName' Default is 'Login' ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 10 Default value: Login Accept pipeline input: False Accept wildcard characters: False ``` ### -NameValue Specify which field to use as NAME value when importing the users. Available options 'FirstName' / 'DisplayName' Default is 'DisplayName' ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 11 Default value: DisplayName Accept pipeline input: False Accept wildcard characters: False ``` ### -AzureAdCredential Use a PSCredential object for connecting with AzureAd ```yaml Type: PSCredential Parameter Sets: (All) Aliases: Required: False Position: 12 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -SkipAzureAd Switch to instruct the cmdlet to skip validating against the Azure Active Directory ```yaml Type: SwitchParameter Parameter Sets: UserListImport Aliases: Required: False Position: 13 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ForceExactAadGroupName Force to find the exact name of the Azure Active Directory Group ```yaml Type: SwitchParameter Parameter Sets: GroupNameImport Aliases: Required: False Position: 14 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -AadGroupId Azure Active directory user group ID containing users to be imported ```yaml Type: String Parameter Sets: GroupIdImport Aliases: Required: True Position: 15 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -EmailValue Specify which field to use as EMAIL value when importing the users. Available options 'Mail' / 'UserPrincipalName' Default is 'Mail' ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 16 Default value: Mail Accept pipeline input: False Accept wildcard characters: False ``` ### -TenantId The TenantId to use when connecting to Azure Active Directory Uses the tenant id of the current environment if not specified. ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 17 Default value: $Script:TenantId Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: User, Users, Security, Configuration, Permission, AAD, Azure Active Directory, Group, Groups Author: Rasmus Andersen (@ITRasmus) Author: Charles Colombel (@dropshind) Author: Mötz Jensen (@Splaxi) Author: Miklós Molnár (@scifimiki) Author: Gert Van der Heyden (@gertvdh) Author: Florian Hopfner (@FH-Inway) At no circumstances can this cmdlet be used to import users into a PROD environment. Only users from an Azure Active Directory that you have access to, can be imported. Use AAD B2B implementation if you want to support external people. Every imported users will get the System Administration / Administrator role assigned on import ## RELATED LINKS ================================================ FILE: docs/Import-D365Bacpac.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Import-D365Bacpac ## SYNOPSIS Import a bacpac file ## SYNTAX ### ImportTier1 (Default) ``` Import-D365Bacpac [-ImportModeTier1] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [-BacpacFile] [-NewDatabaseName] [-CustomSqlFile ] [-ModelFile ] [-DiagnosticFile ] [-ImportOnly] [-MaxParallelism ] [-LogPath ] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [-Properties ] [] ``` ### ImportOnlyTier2 ``` Import-D365Bacpac [-ImportModeTier2] [[-DatabaseServer] ] [[-DatabaseName] ] [-SqlUser] [-SqlPwd] [-BacpacFile] [-NewDatabaseName] [[-AxDeployExtUserPwd] ] [[-AxDbAdminPwd] ] [[-AxRuntimeUserPwd] ] [[-AxMrRuntimeUserPwd] ] [[-AxRetailRuntimeUserPwd] ] [[-AxRetailDataSyncUserPwd] ] [[-AxDbReadonlyUserPwd] ] [-CustomSqlFile ] [-ModelFile ] [-DiagnosticFile ] [-ImportOnly] [-MaxParallelism ] [-LogPath ] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [-Properties ] [] ``` ### ImportTier2 ``` Import-D365Bacpac [-ImportModeTier2] [[-DatabaseServer] ] [[-DatabaseName] ] [-SqlUser] [-SqlPwd] [-BacpacFile] [-NewDatabaseName] [-AxDeployExtUserPwd] [-AxDbAdminPwd] [-AxRuntimeUserPwd] [-AxMrRuntimeUserPwd] [-AxRetailRuntimeUserPwd] [-AxRetailDataSyncUserPwd] [-AxDbReadonlyUserPwd] [-CustomSqlFile ] [-ModelFile ] [-DiagnosticFile ] [-MaxParallelism ] [-LogPath ] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [-Properties ] [] ``` ## DESCRIPTION Import a bacpac file to either a Tier1 or Tier2 environment ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365InstallSqlPackage ``` You should always install the latest version of the SqlPackage.exe, which is used by New-D365Bacpac. This will fetch the latest .Net Core Version of SqlPackage.exe and install it at "C:\temp\d365fo.tools\SqlPackage". ### EXAMPLE 2 ``` Import-D365Bacpac -ImportModeTier1 -BacpacFile "C:\temp\uat.bacpac" -NewDatabaseName "ImportedDatabase" ``` PS C:\\\> Switch-D365ActiveDatabase -NewDatabaseName "ImportedDatabase" This will instruct the cmdlet that the import will be working against a SQL Server instance. It will import the "C:\temp\uat.bacpac" file into a new database named "ImportedDatabase". The next thing to do is to switch the active database out with the new one you just imported. "ImportedDatabase" will be switched in as the active database, while the old one will be named "AXDB_original". ### EXAMPLE 3 ``` 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" ``` PS C:\\\> Switch-D365ActiveDatabase -NewDatabaseName "ImportedDatabase" -SqlUser "sqladmin" -SqlPwd "XyzXyz" This will instruct the cmdlet that the import will be working against an Azure DB instance. It requires all relevant passwords from LCS for all the builtin user accounts used in a Tier 2 environment. It will import the "C:\temp\uat.bacpac" file into a new database named "ImportedDatabase". The next thing to do is to switch the active database out with the new one you just imported. "ImportedDatabase" will be switched in as the active database, while the old one will be named "AXDB_original". ### EXAMPLE 4 ``` Import-D365Bacpac -ImportModeTier1 -BacpacFile "C:\temp\uat.bacpac" -NewDatabaseName "ImportedDatabase" -DiagnosticFile "C:\temp\ImportLog.txt" ``` This will instruct the cmdlet that the import will be working against a SQL Server instance. It will import the "C:\temp\uat.bacpac" file into a new database named "ImportedDatabase". It will output a diagnostic file to "C:\temp\ImportLog.txt". ### EXAMPLE 5 ``` Import-D365Bacpac -ImportModeTier1 -BacpacFile "C:\temp\uat.bacpac" -NewDatabaseName "ImportedDatabase" -DiagnosticFile "C:\temp\ImportLog.txt" -MaxParallelism 32 ``` This will instruct the cmdlet that the import will be working against a SQL Server instance. It will import the "C:\temp\uat.bacpac" file into a new database named "ImportedDatabase". It will output a diagnostic file to "C:\temp\ImportLog.txt". It will use 32 connections against the database server while importing the bacpac file. ### EXAMPLE 6 ``` Import-D365Bacpac -ImportModeTier1 -BacpacFile "C:\temp\uat.bacpac" -NewDatabaseName "ImportedDatabase" -ImportOnly ``` This will instruct the cmdlet that the import will be working against a SQL Server instance. It will import the "C:\temp\uat.bacpac" file into a new database named "ImportedDatabase". No cleanup or prepping jobs will be executed, because this is for importing only. This would be something that you can use when extract a bacpac file from a Tier1 and want to import it into a Tier1. You would still need to execute the Switch-D365ActiveDatabase cmdlet, to get the newly imported database to be the AXDB database. ### EXAMPLE 7 ``` [System.Collections.ArrayList] $PropertiesList = New-Object -TypeName "System.Collections.ArrayList" ``` PS C:\\\> $PropertiesList.Add("DisableIndexesForDataPhase=false") PS C:\\\> Import-D365Bacpac -ImportModeTier1 -BacpacFile "C:\temp\uat.bacpac" -NewDatabaseName "ImportedDatabase" -Properties $PropertiesList.ToArray() This will instruct the cmdlet that the import will be working against a SQL Server instance. It will import the "C:\temp\uat.bacpac" file into a new database named "ImportedDatabase". It will use the DisableIndexesForDataPhase SQLPackage property to disable the index rebuild during the data phase of the import. ## PARAMETERS ### -ImportModeTier1 Switch to instruct the cmdlet that it will import into a Tier1 environment The cmdlet will expect to work against a SQL Server instance ```yaml Type: SwitchParameter Parameter Sets: ImportTier1 Aliases: Required: True Position: 1 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ImportModeTier2 Switch to instruct the cmdlet that it will import into a Tier2 environment The cmdlet will expect to work against an Azure DB instance ```yaml Type: SwitchParameter Parameter Sets: ImportOnlyTier2, ImportTier2 Aliases: Required: True Position: 1 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: ImportTier1 Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: ImportOnlyTier2, ImportTier2 Aliases: Required: True Position: 4 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: ImportTier1 Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: ImportOnlyTier2, ImportTier2 Aliases: Required: True Position: 5 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -BacpacFile Path to the bacpac file you want to import into the database server ```yaml Type: String Parameter Sets: (All) Aliases: File Required: True Position: 6 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -NewDatabaseName Name of the new database that will be created while importing the bacpac file This will create a new database on the database server and import the content of the bacpac into ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 7 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -AxDeployExtUserPwd Password that is obtained from LCS ```yaml Type: String Parameter Sets: ImportOnlyTier2 Aliases: Required: False Position: 8 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: ImportTier2 Aliases: Required: True Position: 8 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -AxDbAdminPwd Password that is obtained from LCS ```yaml Type: String Parameter Sets: ImportOnlyTier2 Aliases: Required: False Position: 9 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: ImportTier2 Aliases: Required: True Position: 9 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -AxRuntimeUserPwd Password that is obtained from LCS ```yaml Type: String Parameter Sets: ImportOnlyTier2 Aliases: Required: False Position: 10 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: ImportTier2 Aliases: Required: True Position: 10 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -AxMrRuntimeUserPwd Password that is obtained from LCS ```yaml Type: String Parameter Sets: ImportOnlyTier2 Aliases: Required: False Position: 11 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: ImportTier2 Aliases: Required: True Position: 11 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -AxRetailRuntimeUserPwd Password that is obtained from LCS ```yaml Type: String Parameter Sets: ImportOnlyTier2 Aliases: Required: False Position: 12 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: ImportTier2 Aliases: Required: True Position: 12 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -AxRetailDataSyncUserPwd Password that is obtained from LCS ```yaml Type: String Parameter Sets: ImportOnlyTier2 Aliases: Required: False Position: 13 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: ImportTier2 Aliases: Required: True Position: 13 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -AxDbReadonlyUserPwd Password that is obtained from LCS ```yaml Type: String Parameter Sets: ImportOnlyTier2 Aliases: Required: False Position: 14 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: ImportTier2 Aliases: Required: True Position: 14 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -CustomSqlFile Path to the sql script file that you want the cmdlet to execute against your data after it has been imported ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ModelFile Path to the model file that you want the SqlPackage.exe to use instead the one being part of the bacpac file This is used to override SQL Server options, like collation and etc ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -DiagnosticFile Path to where you want the import to output a diagnostics file to assist you in troubleshooting the import ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ImportOnly Switch to instruct the cmdlet to only import the bacpac into the new database The cmdlet will create a new database and import the content of the bacpac file into this Nothing else will be executed ```yaml Type: SwitchParameter Parameter Sets: ImportTier1 Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ```yaml Type: SwitchParameter Parameter Sets: ImportOnlyTier2 Aliases: Required: True Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -MaxParallelism Sets SqlPackage.exe's degree of parallelism for concurrent operations running against a database The default value is 8 ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: 8 Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: Named Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ImportBacpac") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Properties String array of properties to be used by SQLPackage.exe See https://learn.microsoft.com/en-us/sql/tools/sqlpackage/sqlpackage-import#properties-specific-to-the-import-action for more information. Note that some properties are already set by the cmdlet, and cannot be overridden. ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Database, Bacpac, Tier1, Tier2, Golden Config, Config, Configuration Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Import-D365Dacpac.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Import-D365Dacpac ## SYNOPSIS Import dacpac file to a database ## SYNTAX ``` Import-D365Dacpac [-Path] [[-ModelFile] ] [[-PublishFile] ] [[-DiagnosticFile] ] [[-MaxParallelism] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-LogPath] ] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [] ``` ## DESCRIPTION Import a dacpac file into a database, using the publish feature of SqlPackage.exe If the database doesn't exists, it will be created If the database exists, the publish process from the dacpac file will make sure to align the different tables inside the database ## EXAMPLES ### EXAMPLE 1 ``` Import-D365Dacpac -Path "c:\Temp\AxDB.dacpac" -ModelFile "c:\Temp\dbo.salestable.model.xml" ``` This will import the dacpac file and use the modified model file while doing so. It will use the "c:\Temp\AxDB.dacpac" as the Path parameter. It will use the "c:\Temp\dbo.salestable.model.xml" as the ModelFile parameter. This is used to enable single table restore / publish. ### EXAMPLE 2 ``` Import-D365Dacpac -Path "c:\Temp\AxDB.dacpac" -ModelFile "c:\Temp\dbo.salestable.model.xml" -DiagnosticFile "C:\temp\ImportLog.txt" -MaxParallelism 32 ``` This will import the dacpac file and use the modified model file while doing so. It will use the "c:\Temp\AxDB.dacpac" as the Path parameter. It will use the "c:\Temp\dbo.salestable.model.xml" as the ModelFile parameter. It will use the "C:\temp\ImportLog.txt" as the DiagnosticFile parameter, where the diagnostic file will be stored. It will use 32 connections against the database server while importing the bacpac file. This is used to enable single table restore / publish. ### EXAMPLE 3 ``` Import-D365Dacpac -Path "c:\Temp\AxDB.dacpac" -PublishFile "c:\Temp\publish.xml" ``` This will import the dacpac file and use the Publish file which contains advanced configuration instructions for SqlPackage.exe. It will use the "c:\Temp\AxDB.dacpac" as the Path parameter. It will use the "c:\Temp\publish.xml" as the PublishFile parameter, which contains advanced configuration instructions for SqlPackage.exe. This is used to enable full restore / publish, but to avoid some of the common pitfalls. ## PARAMETERS ### -Path Path to the dacpac file that you want to import ```yaml Type: String Parameter Sets: (All) Aliases: File, Dacpac Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ModelFile Path to the model file that you want the SqlPackage.exe to use instead the one being part of the dacpac file This is used to override SQL Server options, like collation and etc This is also used to support single table import / restore from a dacpac file ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -PublishFile Path to the publish / profile file that contains extended parameters for the SqlPackage.exe assembly ```yaml Type: String Parameter Sets: (All) Aliases: ProfileFile Required: False Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -DiagnosticFile Path to where you want the import to output a diagnostics file to assist you in troubleshooting the import ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -MaxParallelism Sets SqlPackage.exe's degree of parallelism for concurrent operations running against a database The default value is 8 ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: 8 Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 8 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 9 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 10 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ImportDacpac") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Database, Dacpac, Tier1, Tier2, Golden Config, Config, Configuration Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Import-D365ExternalUser.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Import-D365ExternalUser ## SYNOPSIS Import an user from an external Azure Active Directory (AAD) ## SYNTAX ``` Import-D365ExternalUser [-Id] [-Name] [-Email] [[-Enabled] ] [[-Company] ] [[-Language] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [] ``` ## DESCRIPTION Imports an user from an AAD that is NOT the same as the AAD tenant that the D365FO environment is running under ## EXAMPLES ### EXAMPLE 1 ``` Import-D365ExternalUser -Id "John" -Name "John Doe" -Email "John@contoso.com" ``` This will import an user from an external Azure Active Directory. The new user will get the system wide Id "John". The name of the new user will be "John Doe". The e-mail address / sign-in e-mail address will be registered as "John@contoso.com". ## PARAMETERS ### -Id The internal Id that the user must be imported with The Id has to unique across the entire user base ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Name The display name of the user inside the D365FO environment ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Email The email address of the user that you want to import This is also the sign-in user name / e-mail address to gain access to the system If the external AAD tenant has multiple custom domain names, you have to use the domain that they have configured as default ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Enabled Should the imported user be enabled or not? Default value is 1, which equals true / yes ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: 1 Accept pipeline input: False Accept wildcard characters: False ``` ### -Company Default company that should be configured for the user, for when they sign-in to the D365 environment Default value is "DAT" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: DAT Accept pipeline input: False Accept wildcard characters: False ``` ### -Language Language that should be configured for the user, for when they sign-in to the D365 environment Default value is "en-US" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: En-us Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 8 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 9 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 10 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: User, Users, Security, Configuration, Permission, AAD, Azure Active Directory Author: Anderson Joyle (@AndersonJoyle) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Import-D365Model.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Import-D365Model ## SYNOPSIS Import a model into Dynamics 365 for Finance & Operations ## SYNTAX ``` Import-D365Model [-Path] [[-BinDir] ] [[-MetaDataDir] ] [-Replace] [-LogPath ] [-ShowOriginalProgress] [-OutputCommandOnly] [] ``` ## DESCRIPTION Import a model into a Dynamics 365 for Finance & Operations environment ## EXAMPLES ### EXAMPLE 1 ``` Import-D365Model -Path c:\temp\d365fo.tools\CustomModel.axmodel ``` This will import the "c:\temp\d365fo.tools\CustomModel.axmodel" model into the PackagesLocalDirectory location. ### EXAMPLE 2 ``` Import-D365Model -Path c:\temp\d365fo.tools\CustomModel.axmodel -Replace ``` This will import the "c:\temp\d365fo.tools\CustomModel.axmodel" model into the PackagesLocalDirectory location. If the model already exists it will replace it. ## PARAMETERS ### -Path Path to the axmodel file that you want to import ```yaml Type: String Parameter Sets: (All) Aliases: File Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: "$Script:PackageDirectory\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: "$Script:MetaDataDir" Accept pipeline input: False Accept wildcard characters: False ``` ### -Replace Instruct the cmdlet to replace an already existing model ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: Named Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ModelUtilImport") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: ModelUtil, Axmodel, Model, Import, Replace, Source Control, Vsts, Azure DevOps Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Import-D365RsatSelfServiceCertificates.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Import-D365RsatSelfServiceCertificates ## SYNOPSIS Import certificates for RSAT ## SYNTAX ``` Import-D365RsatSelfServiceCertificates [-Path] [-Password] [] ``` ## DESCRIPTION Import the certificates for RSAT into the correct stores and display the thumbprint 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 ## EXAMPLES ### EXAMPLE 1 ``` Import-D365RsatSelfServiceCertificates -Path "C:\Temp\UAT" -Password "123456789" ``` This will import the .cer and .pxf files into the correct store, bases on the files located in "C:\Temp\UAT". After import it will display the thumbprint for both certificates. Sample output: \[23:43:05\]\[Import-D365RsatSelfServiceCertificates\] Pfx Thumbprint: B4D6921321434235463463414312343253523A05 \[23:43:05\]\[Import-D365RsatSelfServiceCertificates\] Cert Thumbprint: B4D6921321434235463463414312343253523A05 ## PARAMETERS ### -Path Path to the folder where the .cer and .pxf files are located The files needs to be extracted from the zip archive ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Password Password for the .pxf file Working with self-service environments, the password will be displayed during the download of the zip archive ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Initialize-D365RsatCertificate.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Initialize-D365RsatCertificate ## SYNOPSIS Create and configure test automation certificate ## SYNTAX ``` Initialize-D365RsatCertificate [-CertificateFileName ] [-PrivateKeyFileName ] [-Password ] [-CertificateOnly] [-KeepCertificateFile] [-OutputPath ] [] ``` ## DESCRIPTION Creates a new self signed certificate for automated testing and reconfigures the AOS Windows Identity Foundation configuration to trust the certificate ## EXAMPLES ### EXAMPLE 1 ``` Initialize-D365RsatCertificate ``` 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. ### EXAMPLE 2 ``` Initialize-D365RsatCertificate -CertificateOnly ``` This will generate a certificate for issuer 127.0.0.1 and install it in the trusted root certificates. No actions will be taken regarding modifying the AOS wif.config file. Use this when installing RSAT on a machine different from the AOS where RSAT is pointing to. ### EXAMPLE 3 ``` Initialize-D365RsatCertificate -CertificateOnly -KeepCertificateFile ``` This will generate a certificate for issuer 127.0.0.1 and install it in the trusted root certificates. No actions will be taken regarding modifying the AOS wif.config file. The pfx will be copied into the default "c:\temp\d365fo.tools" folder after creation. Use this when installing RSAT on a machine different from the AOS where RSAT is pointing to. The pfx file enables you to import the same certificate across your entire network, instead of creating one per machine. ## PARAMETERS ### -CertificateFileName Filename to be used when exporting the cer file ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: (Join-Path $env:TEMP "TestAuthCert.cer") Accept pipeline input: False Accept wildcard characters: False ``` ### -PrivateKeyFileName Filename to be used when exporting the pfx file ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: (Join-Path $env:TEMP "TestAuthCert.pfx") Accept pipeline input: False Accept wildcard characters: False ``` ### -Password The password that you want to use to protect your certificate with The default value is: "Password1" ```yaml Type: SecureString Parameter Sets: (All) Aliases: Required: False Position: Named Default value: (ConvertTo-SecureString -String "Password1" -Force -AsPlainText) Accept pipeline input: False Accept wildcard characters: False ``` ### -CertificateOnly Switch specifying if only the certificate needs to be created If specified, then only the certificate is created and the thumbprint is not added to the wif.config on the AOS side 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 ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -KeepCertificateFile Instruct the cmdlet to copy the certificate file from the working directory into the desired location specified with OutputPath parameter ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputPath Path to where you want the certificate file exported to, when using the KeepCertificateFile parameter switch Default value is: "c:\temp\d365fo.tools" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Automated Test, Test, Regression, Certificate, Thumbprint Author: Kenny Saelen (@kennysaelen) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Install-D365SupportingSoftware.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Install-D365SupportingSoftware ## SYNOPSIS Install software supporting F&O development ## SYNTAX ``` Install-D365SupportingSoftware [-Name] [-Force] [] ``` ## DESCRIPTION Installs software commonly used when doing Dynamics 365 Finance and Operations development Common ones: fiddler, postman, microsoft-edge, winmerge, notepadplusplus.install, azurepowershell, azure-cli, insomnia-rest-api-client, git.install Full list of software: https://community.chocolatey.org/packages ## EXAMPLES ### EXAMPLE 1 ``` Install-D365SupportingSoftware -Name vscode ``` This will install VSCode on the system. ### EXAMPLE 2 ``` Install-D365SupportingSoftware -Name "vscode","fiddler" ``` This will install VSCode and fiddler on the system. ### EXAMPLE 3 ``` Install-D365SupportingSoftware -Name vscode -Force ``` This will install VSCode on the system, forcing it to be (re)installed. ## PARAMETERS ### -Name The name of the software to install Support a list of softwares that you want to have installed on the system ```yaml Type: String[] Parameter Sets: (All) Aliases: SoftwareName Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Instruct the cmdlet to install the latest version of the software, regardless if it is already present on the system ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Dag Calafell (@dodiggitydag) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365AzCopyTransfer.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365AzCopyTransfer ## SYNOPSIS Transfer a file using AzCopy ## SYNTAX ``` Invoke-D365AzCopyTransfer [-SourceUri] [-DestinationUri] [[-FileName] ] [-DeleteOnTransferComplete] [[-LogPath] ] [-ShowOriginalProgress] [-OutputCommandOnly] [-Force] [-EnableException] [] ``` ## DESCRIPTION Transfer a file using the AzCopy tool You can upload a local file to an Azure Storage Blob Container You can download a file located in an Azure Storage Blob Container to a local folder 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 ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365AzCopyTransfer -SourceUri "https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=..." -DestinationUri "c:\temp\d365fo.tools\GOLDER.bacpac" ``` This will transfer a file from an Azure Storage Blob Container to a local folder/file on the machine. The file that will be transfered/downloaded is SourceUri "https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...". The file will be transfered/downloaded to DestinationUri "c:\temp\d365fo.tools\GOLDER.bacpac". If there exists a file already, the file will NOT be overwritten. ### EXAMPLE 2 ``` Invoke-D365AzCopyTransfer -SourceUri "https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=..." -DestinationUri "c:\temp\d365fo.tools\GOLDER.bacpac" -Force ``` This will transfer a file from an Azure Storage Blob Container to a local folder/file on the machine. The file that will be transfered/downloaded is SourceUri "https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...". The file will be transfered/downloaded to DestinationUri "c:\temp\d365fo.tools\GOLDER.bacpac". If there exists a file already, the file will be overwritten, because Force has been supplied. ### EXAMPLE 3 ``` 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=..." ``` This will transfer a file from an Azure Storage Blob Container to another Azure Storage Blob Container. The file that will be transfered/downloaded is SourceUri "https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...". The file will be transfered/downloaded to DestinationUri "https://456.blob.core.windows.net/targetcontainer/filename?sv=2015-12-11&sr=...". For this to work, you need to make sure both SourceUri and DestinationUri has an valid SAS token/key included. If there exists a file already, the file will NOT be overwritten. ### EXAMPLE 4 ``` Invoke-D365AzCopyTransfer -SourceUri "https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=..." -DestinationUri "c:\temp\d365fo.tools\GOLDER.bacpac" -DeleteOnTransferComplete ``` This will transfer a file from an Azure Storage Blob Container to a local folder/file on the machine. The file that will be transfered/downloaded is SourceUri "https://123.blob.core.windows.net/containername/filename?sv=2015-12-11&sr=...". The file will be transfered/downloaded to DestinationUri "c:\temp\d365fo.tools\GOLDER.bacpac". 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=...". ### EXAMPLE 5 ``` $DestinationParms = Get-D365AzureStorageUrl -OutputAsHashtable ``` PS C:\\\> $BlobFileDetails = Get-D365LcsDatabaseBackups -Latest | Invoke-D365AzCopyTransfer @DestinationParms PS C:\\\> $BlobFileDetails | Invoke-D365AzCopyTransfer -DestinationUri "C:\Temp" -DeleteOnTransferComplete This will transfer the lastest backup file from LCS Asset Library to your local "C:\Temp". It will get a destination Url, for it to transfer the backup file between the LCS storage account and your own. The newly transfered file, that lives in your own storage account, will then be downloaded to your local "c:\Temp". After the file has been downloaded to your local "C:\Temp", it will be deleted from your own storage account. ## PARAMETERS ### -SourceUri Source file uri that you want to transfer ```yaml Type: String Parameter Sets: (All) Aliases: FileLocation, SourceUrl Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -DestinationUri Destination file uri that you want to transfer the file to ```yaml Type: String Parameter Sets: (All) Aliases: DestinationFile Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -FileName 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 ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -DeleteOnTransferComplete Instruct the cmdlet to delete the source file when done transfering Default is $false which will leave the source file ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 4 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\AzCopy") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Instruct the cmdlet to overwrite already existing file ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, File, Files, Latest, Bacpac, Container, LCS, Asset, Library Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. ## RELATED LINKS ================================================ FILE: docs/Invoke-D365AzureDevOpsNugetPush.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365AzureDevOpsNugetPush ## SYNOPSIS Push a package / nuget to Azure DevOps ## SYNTAX ``` Invoke-D365AzureDevOpsNugetPush [[-Path] ] [[-Source] ] [[-LogPath] ] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [] ``` ## DESCRIPTION Push a package / nuget to an Azure DevOps feed ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365AzureDevOpsNugetPush -Path "c:\temp\d365fo.tools\microsoft.dynamics.ax.application.devalm.buildxpp.10.0.605.10014.nupkg" -Source "Contoso" ``` This will push the package / nuget to the Azure DevOps feed. 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". The request will be going to the Azure DevOps instance that is registered with the Source (Name) "Contoso" via the nuget.exe tool. ## PARAMETERS ### -Path Path to the package / nuget that you want to push to the Azure DevOps feed ```yaml Type: String Parameter Sets: (All) Aliases: PackagePath Required: False Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Source The logical name for the nuget source / connection that you want to use while pushing the package / nuget This requires you to register the nuget source, by hand, using the nuget.exe tool directly Base command to use: .\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" Please note that the password is in fact a personal access token and NOT your real password The value specified for Name in the nuget sources command, is the value to supply for Source for this cmdlet ```yaml Type: String Parameter Sets: (All) Aliases: NugetSource, Destination Required: False Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 3 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\Nuget") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365AzureStorageDownload.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365AzureStorageDownload ## SYNOPSIS Download a file to Azure ## SYNTAX ### Default (Default) ``` Invoke-D365AzureStorageDownload [-AccountId ] [-AccessToken ] [-SAS ] [-Container ] -FileName [-Path ] [-Force] [-EnableException] [] ``` ### Latest ``` Invoke-D365AzureStorageDownload [-AccountId ] [-AccessToken ] [-SAS ] [-Container ] [-Path ] [-Latest] [-Force] [-EnableException] [] ``` ## DESCRIPTION Download any file to an Azure Storage Account ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365AzureStorageDownload -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Container "backupfiles" -FileName "OriginalUAT.bacpac" -Path "c:\temp" ``` Will download the "OriginalUAT.bacpac" file from the storage account and save it to "c:\temp\OriginalUAT.bacpac" ### EXAMPLE 2 ``` Invoke-D365AzureStorageDownload -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Container "backupfiles" -Path "c:\temp" -Latest ``` Will download the file with the latest modified datetime from the storage account and save it to "c:\temp\". The complete path to the file will returned as output from the cmdlet. ### EXAMPLE 3 ``` $AzureParams = Get-D365ActiveAzureStorageConfig ``` PS C:\\\> Invoke-D365AzureStorageDownload @AzureParams -Path "c:\temp" -Latest This will get the current Azure Storage Account configuration details and use them as parameters to download the latest file from an Azure Storage Account Will download the file with the latest modified datetime from the storage account and save it to "c:\temp\". The complete path to the file will returned as output from the cmdlet. ### EXAMPLE 4 ``` Invoke-D365AzureStorageDownload -Latest ``` This will use the default parameter values that are based on the configuration stored inside "Get-D365ActiveAzureStorageConfig". Will download the file with the latest modified datetime from the storage account and save it to "c:\temp\d365fo.tools". ### EXAMPLE 5 ``` Invoke-D365AzureStorageDownload -AccountId "miscfiles" -SAS "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" -Container "backupfiles" -Path "c:\temp" -Latest ``` Will download the file with the latest modified datetime from the storage account and save it to "c:\temp\". A SAS key is used to gain access to the container and downloading the file from it. The complete path to the file will returned as output from the cmdlet. ## PARAMETERS ### -AccountId Storage Account Name / Storage Account Id where you want to fetch the file from ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:AzureStorageAccountId Accept pipeline input: False Accept wildcard characters: False ``` ### -AccessToken The token that has the needed permissions for the download action ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:AzureStorageAccessToken Accept pipeline input: False Accept wildcard characters: False ``` ### -SAS The SAS key that you have created for the storage account or blob container ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:AzureStorageSAS Accept pipeline input: False Accept wildcard characters: False ``` ### -Container Name of the blob container inside the storage account you where the file is ```yaml Type: String Parameter Sets: (All) Aliases: Blobname, Blob Required: False Position: Named Default value: $Script:AzureStorageContainer Accept pipeline input: False Accept wildcard characters: False ``` ### -FileName Name of the file that you want to download ```yaml Type: String Parameter Sets: Default Aliases: Name Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Path Path to the folder / location you want to save the file The default path is "c:\temp\d365fo.tools" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -Latest Instruct the cmdlet to download the latest file from Azure regardless of name ```yaml Type: SwitchParameter Parameter Sets: Latest Aliases: GetLatest Required: True Position: 5 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Instruct the cmdlet to overwrite the local file if it already exists ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, File, Files, Latest, Bacpac, Container Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. ## RELATED LINKS ================================================ FILE: docs/Invoke-D365AzureStorageUpload.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365AzureStorageUpload ## SYNOPSIS Upload a file to Azure ## SYNTAX ### Default (Default) ``` Invoke-D365AzureStorageUpload [-AccountId ] [-AccessToken ] [-SAS ] [-Container ] -Filepath [-ContentType ] [-Force] [-DeleteOnUpload] [-EnableException] [] ``` ### Pipeline ``` Invoke-D365AzureStorageUpload [-AccountId ] [-AccessToken ] [-SAS ] [-Container ] -Filepath [-ContentType ] [-Force] [-DeleteOnUpload] [-EnableException] [] ``` ## DESCRIPTION Upload any file to an Azure Storage Account ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365AzureStorageUpload -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Container "backupfiles" -Filepath "c:\temp\bacpac\UAT_20180701.bacpac" -DeleteOnUpload ``` 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. After upload the local file will be deleted. ### EXAMPLE 2 ``` $AzureParams = Get-D365ActiveAzureStorageConfig ``` PS C:\\\> New-D365Bacpac | Invoke-D365AzureStorageUpload @AzureParams This will get the current Azure Storage Account configuration details and use them as parameters to upload the file to an Azure Storage Account. ### EXAMPLE 3 ``` New-D365Bacpac | Invoke-D365AzureStorageUpload ``` This will generate a new bacpac file using the "New-D365Bacpac" cmdlet. The file will be uploaded to an Azure Storage Account using the "Invoke-D365AzureStorageUpload" cmdlet. This will use the default parameter values that are based on the configuration stored inside "Get-D365ActiveAzureStorageConfig" for the "Invoke-D365AzureStorageUpload" cmdlet. ### EXAMPLE 4 ``` Invoke-D365AzureStorageUpload -AccountId "miscfiles" -SAS "sv2018-03-28&siunlisted&src&sigAUOpdsfpoWE976ASDhfjkasdf(5678sdfhk" -Container "backupfiles" -Filepath "c:\temp\bacpac\UAT_20180701.bacpac" -DeleteOnUpload ``` This will upload the "c:\temp\bacpac\UAT_20180701.bacpac" up to the "backupfiles" container, inside the "miscfiles" Azure Storage Account. A SAS key is used to gain access to the container and uploading the file to it. ## PARAMETERS ### -AccountId Storage Account Name / Storage Account Id where you want to store the file ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:AzureStorageAccountId Accept pipeline input: False Accept wildcard characters: False ``` ### -AccessToken The token that has the needed permissions for the upload action ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:AzureStorageAccessToken Accept pipeline input: False Accept wildcard characters: False ``` ### -SAS The SAS key that you have created for the storage account or blob container ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:AzureStorageSAS Accept pipeline input: False Accept wildcard characters: False ``` ### -Container Name of the blob container inside the storage account you want to store the file ```yaml Type: String Parameter Sets: (All) Aliases: Blobname, Blob Required: False Position: Named Default value: $Script:AzureStorageContainer Accept pipeline input: False Accept wildcard characters: False ``` ### -Filepath Path to the file you want to upload ```yaml Type: String Parameter Sets: Default Aliases: Path, File Required: True Position: Named Default value: None Accept pipeline input: True (ByValue) Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: Pipeline Aliases: Path, File Required: True Position: Named Default value: None Accept pipeline input: True (ByValue) Accept wildcard characters: False ``` ### -ContentType Media type of the file that is going to be uploaded The value will be used for the blob property "Content Type". If the parameter is left empty, the commandlet will try to automatically determined the value based on the file's extension. 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. Valid media type values can be found here: https://www.iana.org/assignments/media-types/media-types.xhtml ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Instruct the cmdlet to overwrite the file in the container if it already exists ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -DeleteOnUpload Switch to tell the cmdlet if you want the local file to be deleted after the upload completes ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Azure, Azure Storage, Config, Configuration, Token, Blob, File, Files, Bacpac, Container Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. ## RELATED LINKS ================================================ FILE: docs/Invoke-D365BestPractice.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365BestPractice ## SYNOPSIS Run the Best Practice ## SYNTAX ``` Invoke-D365BestPractice [-Module] [-Model] [[-BinDir] ] [[-MetaDataDir] ] [-PackagesRoot] [[-LogPath] ] [-ShowOriginalProgress] [-RunFixers] [-OutputCommandOnly] [] ``` ## DESCRIPTION Run the Best Practice checks against modules and models ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365BestPractice -module "ApplicationSuite" -model "MyOverLayerModel" ``` This will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module. The default output will be silenced. The XML log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.xml". The log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.log". ### EXAMPLE 2 ``` Invoke-D365BestPractice -module "ApplicationSuite" -model "MyOverLayerModel" -PackagesRoot ``` This will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module. We use the binary metadata to look for the module and model. The default output will be silenced. The XML log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.xml". The log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.log". ### EXAMPLE 3 ``` Invoke-D365BestPractice -module "ApplicationSuite" -model "MyOverLayerModel" -ShowOriginalProgress ``` This will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module. The output from the best practice check process will be written to the console / host. The XML log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.xml". The log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.log". ### EXAMPLE 4 ``` Invoke-D365BestPractice -module "ApplicationSuite" -model "MyOverLayerModel" -RunFixers ``` This will execute the best practice checks against MyOverLayerModel in the ApplicationSuite Module. The default output will be silenced. The XML log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.xml". The log file will be written to "c:\temp\d365fo.tools\ApplicationSuite\Dynamics.AX.MyOverLayerModel.xppbp.log". Instructs the xppbp tool to run the fixers for all identified warnings. ## PARAMETERS ### -Module Name of the Module to analyse ```yaml Type: String Parameter Sets: (All) Aliases: ModuleName Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Model Name of the Model to analyse ```yaml Type: String Parameter Sets: (All) Aliases: ModelName Required: True Position: 2 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: "$Script:PackageDirectory\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: "$Script:MetaDataDir" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackagesRoot Instructs the cmdlet to use binary metadata ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath Path where you want to store the log outputs generated from the best practice analyser Also used as the path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 5 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\BestPractice") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -RunFixers Instructs the cmdlet to invoke the fixers for the identified warnings ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### [PsCustomObject] ## NOTES Tags: Best Practice, BP, BPs, Module, Model, Quality Author: Gert Van Der Heyden (@gertvdheyden) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365CompilerResultAnalyzer.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365CompilerResultAnalyzer ## SYNOPSIS Analyze the compiler output log ## SYNTAX ``` Invoke-D365CompilerResultAnalyzer [-Path] [[-OutputPath] ] [-SkipWarnings] [-SkipTasks] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Analyze the compiler output log and generate an excel file contain worksheets per type: Errors, Warnings, Tasks It could be a Visual Studio compiler log or it could be a Invoke-D365ModuleCompile log you want analyzed ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365CompilerResultAnalyzer -Path "c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log" ``` This will analyse all compiler output log files generated from Visual Studio. It will use the default path for the OutputPath parameter. It will build error and error summary worksheets. It will build warning and warning summary worksheets. It will build task and task summary worksheets. A result set example: File Filename ---- -------- c:\temp\d365fo.tools\Custom-CompilerResults.xlsx Custom-CompilerResults.xlsx ### EXAMPLE 2 ``` Invoke-D365CompilerResultAnalyzer -Path "c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log" -SkipWarnings ``` This will analyse all compiler output log files generated from Visual Studio. It will use the default path for the OutputPath parameter. It will build error and error summary worksheets. It will build task and task summary worksheets. A result set example: File Filename ---- -------- c:\temp\d365fo.tools\Custom-CompilerResults.xlsx Custom-CompilerResults.xlsx ### EXAMPLE 3 ``` Invoke-D365CompilerResultAnalyzer -Path "c:\temp\d365fo.tools\Custom\Dynamics.AX.Custom.xppc.log" -SkipTasks ``` This will analyse all compiler output log files generated from Visual Studio. It will use the default path for the OutputPath parameter. It will build error and error summary worksheets. It will build warning and warning summary worksheets. A result set example: File Filename ---- -------- c:\temp\d365fo.tools\Custom-CompilerResults.xlsx Custom-CompilerResults.xlsx ## PARAMETERS ### -Path Path to the compiler log file that you want to work against A BuildModelResult.log or a Dynamics.AX.*.xppc.log file will both work ```yaml Type: String Parameter Sets: (All) Aliases: LogFile Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -OutputPath Path where you want the excel file (xlsx-file) saved to ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -SkipWarnings Instructs the cmdlet to skip warnings while analyzing the compiler output log file ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -SkipTasks Instructs the cmdlet to skip tasks while analyzing the compiler output log file ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Default path is the same as the AOS service "PackagesLocalDirectory" directory Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Compiler, Build, Errors, Warnings, Tasks Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Vilmos Kintera" (twitter: @DAXRunBase) All credits goes to him for showing how to extract these information His blog can be found here: https://www.daxrunbase.com/blog/ The specific blog post that we based this cmdlet on can be found here: https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/ The github repository containing the original scrips can be found here: https://github.com/DAXRunBase/PowerShell-and-Azure ## RELATED LINKS ================================================ FILE: docs/Invoke-D365DBSync.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365DbSync ## SYNOPSIS Invoke the synchronization process used in Visual Studio ## SYNTAX ``` Invoke-D365DbSync [[-BinDirTools] ] [[-MetadataDir] ] [[-SyncMode] ] [[-Verbosity] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-LogPath] ] [-ShowOriginalProgress] [-OutputCommandOnly] [] ``` ## DESCRIPTION Uses the sync.exe (engine) to synchronize the database for the environment ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365DBSync ``` This will invoke the sync engine and have it work against the database. ### EXAMPLE 2 ``` Invoke-D365DBSync -Verbose ``` 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. ## PARAMETERS ### -BinDirTools Path to where the tools on the machine can be found Default value is normally the AOS Service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:BinDirTools Accept pipeline input: False Accept wildcard characters: False ``` ### -MetadataDir Path to where the tools on the machine can be found Default value is normally the AOS Service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -SyncMode The sync mode the sync engine will use Default value is: "FullAll" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: FullAll Accept pipeline input: False Accept wildcard characters: False ``` ### -Verbosity Parameter used to instruct the level of verbosity the sync engine has to report back Default value is: "Normal" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: Normal Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 8 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 9 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\DbSync") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Database, Sync, SyncDB, Synchronization, Servicing Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) When running the 'FullAll' (default) the command requires an elevated console / Run As Administrator. ## RELATED LINKS ================================================ FILE: docs/Invoke-D365DBSyncPartial.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365DbSyncPartial ## SYNOPSIS Invoke the synchronization process used in Visual Studio ## SYNTAX ``` Invoke-D365DbSyncPartial [[-SyncList] ] [[-SyncExtensionsList] ] [[-SyncMode] ] [[-Verbosity] ] [[-BinDirTools] ] [[-MetadataDir] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-LogPath] ] [-ShowOriginalProgress] [-OutputCommandOnly] [] ``` ## DESCRIPTION Uses the sync.exe (engine) to synchronize the database for the environment ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365DBSyncPartial -SyncList "CustCustomerEntity","SalesTable" ``` This will invoke the sync engine and have it work against the database. It will run with the default value "PartialList" as the SyncMode. It will run the sync process against "CustCustomerEntity" and "SalesTable" ### EXAMPLE 2 ``` Invoke-D365DBSyncPartial -SyncList "CustCustomerEntity","SalesTable" -Verbose ``` This will invoke the sync engine and have it work against the database. It will run with the default value "PartialList" as the SyncMode. It will run the sync process against "CustCustomerEntity" and "SalesTable" It will output the same level of details that Visual Studio would normally do. ### EXAMPLE 3 ``` Invoke-D365DBSyncPartial -SyncList "CustCustomerEntity","SalesTable" -SyncExtensionsList "CaseLog.Extension","CategoryTable.Extension" -Verbose ``` This will invoke the sync engine and have it work against the database. It will run with the default value "PartialList" as the SyncMode. It will run the sync process against "CustCustomerEntity", "SalesTable", "CaseLog.Extension" and "CategoryTable.Extension" It will output the same level of details that Visual Studio would normally do. ## PARAMETERS ### -SyncList The list of objects that you want to pass on to the database synchronoziation engine ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -SyncExtensionsList The list of extension objects that you want to pass on to the database synchronoziation engine ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -SyncMode The sync mode the sync engine will use Default value is: "PartialList" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: PartialList Accept pipeline input: False Accept wildcard characters: False ``` ### -Verbosity Parameter used to instruct the level of verbosity the sync engine has to report back Default value is: "Normal" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: Normal Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDirTools Path to where the tools on the machine can be found Default value is normally the AOS Service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:BinDirTools Accept pipeline input: False Accept wildcard characters: False ``` ### -MetadataDir Path to where the tools on the machine can be found Default value is normally the AOS Service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 8 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 9 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 10 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 11 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\DbSync") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Database, Sync, SyncDB, Synchronization, Servicing Author: Mötz Jensen (@Splaxi) Author: Jasper Callens - Cegeka Inspired by: https://axdynamx.blogspot.com/2017/10/how-to-synchronize-manually-database.html ## RELATED LINKS ================================================ FILE: docs/Invoke-D365DataFlush.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365DataFlush ## SYNOPSIS Invoke the one of the data flush classes ## SYNTAX ``` Invoke-D365DataFlush [[-Url] ] [-Class ] [] ``` ## DESCRIPTION Invoke one of the runnable classes that is clearing cache, data or something else ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365DataFlush ``` This will make a call against the default URL for the machine and have it execute the SysFlushAOD class. ### EXAMPLE 2 ``` Invoke-D365DataFlush -Class SysFlushData,SysFlushAod ``` This will make a call against the default URL for the machine and have it execute the SysFlushData and SysFlushAod classes. ## PARAMETERS ### -Url URL to the Dynamics 365 instance you want to clear the AOD cache on ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Class The class that you want to execute. Default value is "SysFlushAod" ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: Named Default value: SysFlushAod Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Flush, Url, Servicing Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365DbSyncModule.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365DbSyncModule ## SYNOPSIS Synchronize all sync base and extension elements based on a modulename ## SYNTAX ``` Invoke-D365DbSyncModule [-Module] [[-Verbosity] ] [[-BinDirTools] ] [[-MetadataDir] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-LogPath] ] [-ShowOriginalProgress] [-OutputCommandOnly] [] ``` ## DESCRIPTION Retrieve the list of installed packages / modules where the name fits the ModelName parameter. 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 ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365DbSyncModule -Module "MyModel1" ``` It will start the sync process against all tables, views, data entities, table-extensions, view-extensions and data entities-extensions of MyModel1. ### EXAMPLE 2 ``` Invoke-D365DbSyncModule -Module "MyModel1","MyModel2" ``` 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. ### EXAMPLE 3 ``` Get-D365Module -Name "MyModel*" | Invoke-D365DbSyncModule ``` Retrieve the list of installed packages / modules where the name fits the search "MyModel*". The result is: MyModel1 MyModel2 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. ## PARAMETERS ### -Module Name of the model you want to sync tables and table extensions Supports an array of module names ```yaml Type: String[] Parameter Sets: (All) Aliases: ModuleName Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -Verbosity Parameter used to instruct the level of verbosity the sync engine has to report back Default value is: "Normal" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: Normal Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDirTools Path to where the tools on the machine can be found Default value is normally the AOS Service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:BinDirTools Accept pipeline input: False Accept wildcard characters: False ``` ### -MetadataDir Path to where the tools on the machine can be found Default value is normally the AOS Service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 8 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file will be saved ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 9 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\DbSync") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Database, Sync, SyncDB, Synchronization, Servicing Author: Jasper Callens - Cegeka Author: Caleb Blanchard (@daxcaleb) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365GenerateReportAggregateDataEntity.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365GenerateReportAggregateDataEntity ## SYNOPSIS Generate Report for Aggregate Data Entity ## SYNTAX ``` Invoke-D365GenerateReportAggregateDataEntity [[-OutputPath] ] [[-BinDir] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Aggregate Data Entities and generate a metadata report ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365GenerateReportAggregateDataEntity ``` This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" ## PARAMETERS ### -OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE ## RELATED LINKS ================================================ FILE: docs/Invoke-D365GenerateReportAggregateMeasure.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365GenerateReportAggregateMeasure ## SYNOPSIS Generate Report for Aggregate Measure ## SYNTAX ``` Invoke-D365GenerateReportAggregateMeasure [[-OutputPath] ] [[-BinDir] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Aggregate Measures and generate a metadata report ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365GenerateReportAggregateMeasure ``` This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" ## PARAMETERS ### -OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE ## RELATED LINKS ================================================ FILE: docs/Invoke-D365GenerateReportConfigKey.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365GenerateReportConfigKey ## SYNOPSIS Generate Report for Config Key ## SYNTAX ``` Invoke-D365GenerateReportConfigKey [[-OutputPath] ] [[-BinDir] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Config Keys and generate a metadata report ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365GenerateReportConfigKey ``` This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" ## PARAMETERS ### -OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE ## RELATED LINKS ================================================ FILE: docs/Invoke-D365GenerateReportConfigKeyGroup.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365GenerateReportConfigKeyGroup ## SYNOPSIS Generate Report for Config Key Group ## SYNTAX ``` Invoke-D365GenerateReportConfigKeyGroup [[-OutputPath] ] [[-BinDir] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Config Key Groups and generate a metadata report ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365GenerateReportConfigKeyGroup ``` This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" ## PARAMETERS ### -OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE ## RELATED LINKS ================================================ FILE: docs/Invoke-D365GenerateReportDataEntity.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365GenerateReportDataEntity ## SYNOPSIS Generate Report for Data Entity ## SYNTAX ``` Invoke-D365GenerateReportDataEntity [[-OutputPath] ] [[-BinDir] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Data Entities and generate a metadata report ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365GenerateReportDataEntity ``` This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" ## PARAMETERS ### -OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE ## RELATED LINKS ================================================ FILE: docs/Invoke-D365GenerateReportDataEntityField.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365GenerateReportDataEntityField ## SYNOPSIS Generate Report for Data Entity with fields ## SYNTAX ``` Invoke-D365GenerateReportDataEntityField [[-OutputPath] ] [[-BinDir] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Data Entities with their fields and generate a metadata report ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365GenerateReportDataEntityField ``` This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" ## PARAMETERS ### -OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE ## RELATED LINKS ================================================ FILE: docs/Invoke-D365GenerateReportKpi.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365GenerateReportKpi ## SYNOPSIS Generate Report for KPI ## SYNTAX ``` Invoke-D365GenerateReportKpi [[-OutputPath] ] [[-BinDir] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all KPIs and generate a metadata report ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365GenerateReportKpi ``` This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" ## PARAMETERS ### -OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE ## RELATED LINKS ================================================ FILE: docs/Invoke-D365GenerateReportLicenseCode.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365GenerateReportLicenseCode ## SYNOPSIS Generate Report for License Code ## SYNTAX ``` Invoke-D365GenerateReportLicenseCode [[-OutputPath] ] [[-BinDir] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all License Codes and generate a metadata report ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365GenerateReportLicenseCode ``` This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" ## PARAMETERS ### -OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE ## RELATED LINKS ================================================ FILE: docs/Invoke-D365GenerateReportMenuItem.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365GenerateReportMenuItem ## SYNOPSIS Generate Report for Menu Item ## SYNTAX ``` Invoke-D365GenerateReportMenuItem [[-OutputPath] ] [[-BinDir] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all types of Menu Items and generate a metadata report ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365GenerateReportMenuItem ``` This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" ## PARAMETERS ### -OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE ## RELATED LINKS ================================================ FILE: docs/Invoke-D365GenerateReportSsrs.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365GenerateReportSsrs ## SYNOPSIS Generate Report for SSRS Report ## SYNTAX ``` Invoke-D365GenerateReportSsrs [[-OutputPath] ] [[-BinDir] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all SSRS Reports and generate a metadata report ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365GenerateReportSsrs ``` This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" ## PARAMETERS ### -OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE ## RELATED LINKS ================================================ FILE: docs/Invoke-D365GenerateReportTable.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365GenerateReportTable ## SYNOPSIS Generate Report for Table ## SYNTAX ``` Invoke-D365GenerateReportTable [[-OutputPath] ] [[-BinDir] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Tables and generate a metadata report ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365GenerateReportTable ``` This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" ## PARAMETERS ### -OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE ## RELATED LINKS ================================================ FILE: docs/Invoke-D365GenerateReportWorkflowType.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365GenerateReportWorkflowType ## SYNOPSIS Generate Report for Workflow Type ## SYNTAX ``` Invoke-D365GenerateReportWorkflowType [[-OutputPath] ] [[-BinDir] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all Workflow Types and generate a metadata report ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365GenerateReportWorkflowType ``` This will generate a report. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" ## PARAMETERS ### -OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) MIT License Copyright (c) Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE ## RELATED LINKS ================================================ FILE: docs/Invoke-D365GenerateReports.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365GenerateReports ## SYNOPSIS Generate Report for all related objects ## SYNTAX ``` Invoke-D365GenerateReports [[-OutputPath] ] [[-BinDir] ] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Traverse the Dynamics 365 Finance & Operations code repository for all related objects and generate a metadata report for each ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365GenerateReports ``` This will generate a report for each related object. It will contain all the metadata and save it into a xlsx (Excel) file. It will saved the file to "c:\temp\d365fo.tools\" ## PARAMETERS ### -OutputPath Path to where you want the report file to be saved The default value is: "c:\temp\d365fo.tools\" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Normally it is located under the AOSService directory in "PackagesLocalDirectory" Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Metadata, Report, Documentation Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365InstallAzCopy.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365InstallAzCopy ## SYNOPSIS Download AzCopy.exe to your machine ## SYNTAX ``` Invoke-D365InstallAzCopy [[-Url] ] [[-Path] ] [] ``` ## DESCRIPTION Download and extract the AzCopy.exe to your machine ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365InstallAzCopy -Path "C:\temp\d365fo.tools\AzCopy\AzCopy.exe" ``` This will update the path for the AzCopy.exe in the modules configuration ## PARAMETERS ### -Url Url/Uri to where the latest AzCopy download is located The default value is for v10 as of writing ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: Https://aka.ms/downloadazcopy-v10-windows Accept pipeline input: False Accept wildcard characters: False ``` ### -Path Path to where you want the AzCopy to be extracted to Default value is: "C:\temp\d365fo.tools\AzCopy\AzCopy.exe" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: C:\temp\d365fo.tools\AzCopy\AzCopy.exe Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365InstallLicense.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365InstallLicense ## SYNOPSIS Install a license for a 3. party solution ## SYNTAX ``` Invoke-D365InstallLicense [-Path] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-MetaDataDir] ] [[-BinDir] ] [[-LogPath] ] [-ShowOriginalProgress] [-OutputCommandOnly] [] ``` ## DESCRIPTION Install a license for a 3. party solution using the builtin "Microsoft.Dynamics.AX.Deployment.Setup.exe" executable ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365InstallLicense -Path c:\temp\d365fo.tools\license.txt ``` 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. ### EXAMPLE 2 ``` Invoke-D365InstallLicense -Path c:\temp\d365fo.tools\license.txt -ShowOriginalProgress ``` 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. The output from the installation process will be written to the console / host. ## PARAMETERS ### -Path Path to the license file ```yaml Type: String Parameter Sets: (All) Aliases: File Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: "$Script:MetaDataDir" Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: "$Script:BinDir" Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 8 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\InstallLicense") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: License, Install, ISV, 3. Party, Servicing Author: Mötz Jensen (@splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365InstallNuget.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365InstallNuget ## SYNOPSIS Download nuget.exe to your machine ## SYNTAX ``` Invoke-D365InstallNuget [[-Path] ] [[-Url] ] [] ``` ## DESCRIPTION Download the nuget.exe to your machine By default it will download the latest version ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365InstallNuget ``` This will download the latest version of nuget. The install path is identified by the default value: "C:\temp\d365fo.tools\nuget\nuget.exe". ## PARAMETERS ### -Path Path to where you want the nuget.exe to be downloaded to Default value is: "C:\temp\d365fo.tools\nuget\nuget.exe" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: C:\temp\d365fo.tools\nuget Accept pipeline input: False Accept wildcard characters: False ``` ### -Url Url/Uri to where the latest nuget download is located The default value is "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: Https://dist.nuget.org/win-x86-commandline/latest/nuget.exe Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365InstallSqlPackage.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365InstallSqlPackage ## SYNOPSIS Download SqlPackage.exe to your machine ## SYNTAX ### ImportUrl (Default) ``` Invoke-D365InstallSqlPackage [-Path ] [-Url ] [] ``` ### ImportLatest ``` Invoke-D365InstallSqlPackage [-Path ] [-Latest] [] ``` ## DESCRIPTION Download and extract SqlPackage.exe to your machine. ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365InstallSqlPackage ``` This will download and extract SqlPackage.exe. It will use the default value for the Path parameter, for where to save the SqlPackage.exe. It will update the path for the SqlPackage.exe in configuration. ### EXAMPLE 2 ``` Invoke-D365InstallSqlPackage -Path "C:\temp\SqlPackage" ``` This will download and extract SqlPackage.exe. It will save the SqlPackage.exe to "C:\temp\SqlPackage". It will update the path for the SqlPackage.exe in configuration. ### EXAMPLE 3 ``` Invoke-D365InstallSqlPackage -Latest ``` This will download and extract the latest SqlPackage.exe. It will use https://aka.ms/sqlpackage-windows as the download URL. It will update the path for the SqlPackage.exe in configuration. ### EXAMPLE 4 ``` Invoke-D365InstallSqlPackage -Url "https://go.microsoft.com/fwlink/?linkid=3030303" ``` This will download and extract SqlPackage.exe. It will rely on the Url parameter to base the download on. It will use the "https://go.microsoft.com/fwlink/?linkid=3030303" as value for the Url parameter. It will update the path for the SqlPackage.exe in configuration. ## PARAMETERS ### -Path Path to where you want the SqlPackage to be extracted to Default value is: "C:\temp\d365fo.tools\SqlPackage\SqlPackage.exe" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: C:\temp\d365fo.tools\SqlPackage Accept pipeline input: False Accept wildcard characters: False ``` ### -Latest Overrides the Url parameter and uses the latest download URL provided by the evergreen link https://aka.ms/sqlpackage-windows ```yaml Type: SwitchParameter Parameter Sets: ImportLatest Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Url Url/Uri to where the SqlPackage download is located The default value is for version 162.2.111.2 as of writing. Further discussion can be found here: https://github.com/d365collaborative/d365fo.tools/discussions/816 ```yaml Type: String Parameter Sets: ImportUrl Aliases: Required: False Position: Named Default value: Https://go.microsoft.com/fwlink/?linkid=2261576 Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) Author: Florian Hopfner (@FH-Inway) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365LcsApiRefreshToken.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365LcsApiRefreshToken ## SYNOPSIS Refresh the token for lcs communication ## SYNTAX ### Object ``` Invoke-D365LcsApiRefreshToken -ClientId [-InputObject ] [-EnableException] [] ``` ### Simple ``` Invoke-D365LcsApiRefreshToken -ClientId -RefreshToken [-EnableException] [] ``` ## DESCRIPTION Invoke the refresh logic that refreshes the token object based on the ClientId and RefreshToken ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365LcsApiRefreshToken -ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" -RefreshToken "Tsdljfasfe2j32324" ``` This will refresh an OAuth 2.0 access token, and obtain a (new) valid OAuth 2.0 access token from Azure Active Directory. The ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" is used in the OAuth 2.0 "Refresh Token" Grant Flow to authenticate. The RefreshToken "Tsdljfasfe2j32324" is used to prove to Azure Active Directoy that we are allowed to obtain a new valid Access Token. ### EXAMPLE 2 ``` $temp = Get-D365LcsApiToken -LcsApiUri "https://lcsapi.eu.lcs.dynamics.com" -ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" -Username "serviceaccount@domain.com" -Password "TopSecretPassword" ``` PS C:\\\> $temp = Invoke-D365LcsApiRefreshToken -ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" -InputObject $temp This will refresh an OAuth 2.0 access token, and obtain a (new) valid OAuth 2.0 access token from Azure Active Directory. This will obtain a new token object from the Get-D365LcsApiToken cmdlet and store it in $temp. Then it will pass $temp to the Invoke-D365LcsApiRefreshToken along with the ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929". The new token object will be save into $temp. ### EXAMPLE 3 ``` Get-D365LcsApiConfig | Invoke-D365LcsApiRefreshToken | Set-D365LcsApiConfig ``` This will refresh an OAuth 2.0 access token, and obtain a (new) valid OAuth 2.0 access token from Azure Active Directory. This will fetch the current LCS API details from Get-D365LcsApiConfig. The output from Get-D365LcsApiConfig is piped directly to Invoke-D365LcsApiRefreshToken, which will fetch a new token object. The new token object is piped directly into Set-D365LcsApiConfig, which will save the needed details into the configuration store. ## PARAMETERS ### -ClientId The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal ```yaml Type: String Parameter Sets: Object Aliases: Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: Simple Aliases: Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -RefreshToken The Refresh Token that you want to use for the authentication process ```yaml Type: String Parameter Sets: Simple Aliases: Token, refresh_token Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -InputObject The entire object that you received from the Get-D365LcsApiToken command, which contains the needed RefreshToken ```yaml Type: PSObject Parameter Sets: Object Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: LCS, API, Token, BearerToken Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Get-D365LcsApiConfig]() [Get-D365LcsApiToken]() [Get-D365LcsAssetValidationStatus]() [Get-D365LcsDeploymentStatus]() [Invoke-D365LcsDeployment]() [Invoke-D365LcsUpload]() [Set-D365LcsApiConfig]() ================================================ FILE: docs/Invoke-D365LcsDatabaseExport.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365LcsDatabaseExport ## SYNOPSIS Start a database export from an environment ## SYNTAX ``` Invoke-D365LcsDatabaseExport [[-ProjectId] ] [[-BearerToken] ] [-SourceEnvironmentId] [-BackupName] [[-LcsApiUri] ] [-SkipInitialStatusFetch] [-FailOnErrorMessage] [[-RetryTimeout] ] [-EnableException] [] ``` ## DESCRIPTION Start a database export from an environment from a LCS project ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365LcsDatabaseExport -ProjectId 123456789 -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -BackupName "BackupViaApi" -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" ``` This will start the database export from the Source environment. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The backup name is identified by the BackupName "BackupViaApi", which instructs the API to save the backup with that filename. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). ### EXAMPLE 2 ``` Invoke-D365LcsDatabaseExport -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -BackupName "BackupViaApi" ``` This will start the database export from the Source environment. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The backup name is identified by the BackupName "BackupViaApi", which instructs the API to save the backup with that filename. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 3 ``` $databaseExport = Invoke-D365LcsDatabaseExport -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -BackupName "BackupViaApi" -SkipInitialStatusFetch ``` PS C:\\\> $databaseExport | Get-D365LcsDatabaseOperationStatus -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e9" -SleepInSeconds 60 This will start the database export from the Source environment. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The backup name is identified by the BackupName "BackupViaApi", which instructs the API to save the backup with that filename. It will skip the first database operation status fetch and only output the details from starting the export. 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. Will pipe the $databaseExport variable to the Get-D365LcsDatabaseOperationStatus cmdlet and get the status from the database export job. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 4 ``` Invoke-D365LcsDatabaseExport -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -BackupName "BackupViaApi" -SkipInitialStatusFetch ``` This will start the database export from the Source environment. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The backup name is identified by the BackupName "BackupViaApi", which instructs the API to save the backup with that filename. It will skip the first database operation status fetch and only output the details from starting the export. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 5 ``` Invoke-D365LcsDatabaseExport -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -BackupName "BackupViaApi" -RetryTimeout "00:01:00" ``` This will start the database export from the Source environment, and allow for the cmdlet to retry for no more than 1 minute. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The backup name is identified by the BackupName "BackupViaApi", which instructs the API to save the backup with that filename. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: 2 Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -SourceEnvironmentId The unique id of the environment that you want to use as the source for the database export The Id can be located inside the LCS portal ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -BackupName Name of the backup file when it is being exported from the environment The file shouldn't contain any extension at all, just the desired file name ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 4 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -SkipInitialStatusFetch Instruct the cmdlet to skip the first fetch of the database refresh status Useful when you have a large script that handles this status validation and you don't want to spend time with this cmdlet 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. Setting this parameter (activate it), will affect the number of output objects. If you skip, only the first response object outputted. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES 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). 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. 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. Setting the SkipInitialStatusFetch parameter (activate it), will affect the number of output objects. If you skip, only the first response object outputted. 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. Tags: Environment, Config, Configuration, LCS, Database backup, Api, Backup, Bacpac Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Get-D365LcsDatabaseOperationStatus]() [Get-D365LcsApiConfig]() [Get-D365LcsApiToken]() [Get-D365LcsAssetValidationStatus]() [Get-D365LcsDeploymentStatus]() [Invoke-D365LcsApiRefreshToken]() [Invoke-D365LcsUpload]() [Set-D365LcsApiConfig]() ================================================ FILE: docs/Invoke-D365LcsDatabaseRefresh.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365LcsDatabaseRefresh ## SYNOPSIS Start a database refresh between 2 environments ## SYNTAX ``` Invoke-D365LcsDatabaseRefresh [[-ProjectId] ] [[-BearerToken] ] [-SourceEnvironmentId] [-TargetEnvironmentId] [[-LcsApiUri] ] [-SkipInitialStatusFetch] [-FailOnErrorMessage] [[-RetryTimeout] ] [-EnableException] [] ``` ## DESCRIPTION Start a database refresh between 2 environments from a LCS project ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365LcsDatabaseRefresh -ProjectId 123456789 -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" ``` This will start the database refresh between the Source and Target environments. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The target environment is identified by the TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). ### EXAMPLE 2 ``` Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" ``` This will start the database refresh between the Source and Target environments. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The target environment is identified by the TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 3 ``` $databaseRefresh = Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -SkipInitialStatusFetch ``` PS C:\\\> $databaseRefresh | Get-D365LcsDatabaseOperationStatus -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e9" -SleepInSeconds 60 This will start the database refresh between the Source and Target environments. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The target environment is identified by the TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. It will skip the first database refesh status fetch and only output the details from starting the refresh. 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. Will pipe the $databaseRefresh variable to the Get-D365LcsDatabaseOperationStatus cmdlet and get the status from the database refresh job. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 4 ``` Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -SkipInitialStatusFetch ``` This will start the database refresh between the Source and Target environments. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The target environment is identified by the TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. It will skip the first database refesh status fetch and only output the details from starting the refresh. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 5 ``` Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -RetryTimeout "00:01:00" ``` 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. The source environment is identified by the SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae", which can be obtained in the LCS portal. The target environment is identified by the TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: 2 Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -SourceEnvironmentId The unique id of the environment that you want to use as the source for the database refresh The Id can be located inside the LCS portal ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -TargetEnvironmentId The unique id of the environment that you want to use as the target for the database refresh The Id can be located inside the LCS portal ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 4 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -SkipInitialStatusFetch Instruct the cmdlet to skip the first fetch of the database refresh status Useful when you have a large script that handles this status validation and you don't want to spend time with this cmdlet 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. Setting this parameter (activate it), will affect the number of output objects. If you skip, only the first response object outputted. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES 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). 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. 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. Setting the SkipInitialStatusFetch parameter (activate it), will affect the number of output objects. If you skip, only the first response object outputted. 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. Tags: Environment, Config, Configuration, LCS, Database backup, Api, Backup, Restore, Refresh Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Get-D365LcsApiConfig]() [Get-D365LcsApiToken]() [Get-D365LcsAssetValidationStatus]() [Get-D365LcsDeploymentStatus]() [Invoke-D365LcsApiRefreshToken]() [Invoke-D365LcsUpload]() [Set-D365LcsApiConfig]() ================================================ FILE: docs/Invoke-D365LcsDeployment.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365LcsDeployment ## SYNOPSIS Start the deployment of a deployable package ## SYNTAX ### VM (Default) ``` Invoke-D365LcsDeployment [-ProjectId ] -AssetId -EnvironmentId [-BearerToken ] [-LcsApiUri ] [-FailOnErrorMessage] [-RetryTimeout ] [-EnableException] [] ``` ### Self-Service ``` Invoke-D365LcsDeployment [-ProjectId ] -AssetId -EnvironmentId -UpdateName [-BearerToken ] [-LcsApiUri ] [-FailOnErrorMessage] [-RetryTimeout ] [-EnableException] [] ``` ## DESCRIPTION Deploy a deployable package from the Asset Library from a LCS project using the API provided by Microsoft ## EXAMPLES ### EXAMPLE 1 ``` 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" ``` This will start the deployment of the file located in the Asset Library. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. 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. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "Bearer JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). ### EXAMPLE 2 ``` Invoke-D365LcsDeployment -AssetId "958ae597-f089-4811-abbd-c1190917eaae" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" ``` This will start the deployment of the file located in the Asset Library. 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. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 3 ``` Invoke-D365LcsDeployment -AssetId "958ae597-f089-4811-abbd-c1190917eaae" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -UpdateName "Release_XYZ" ``` This will start the deployment of the file located in the Asset Library against a Self-Service environment. 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. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The deployment is name "Release_XYZ" by setting the UpdateName parameter, which is mandatory when working against Self-Service environments. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 4 ``` Invoke-D365LcsDeployment -AssetId "958ae597-f089-4811-abbd-c1190917eaae" -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -RetryTimeout "00:01:00" ``` 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. 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. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -AssetId The unique id of the asset / file that you are trying to deploy from LCS ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -EnvironmentId The unique id of the environment that you want to work against The Id can be located inside the LCS portal Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -UpdateName Name of the update when you are working against Self-Service environments ```yaml Type: String Parameter Sets: Self-Service Aliases: Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: Named Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: Named Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token, Deployment, Deploy Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Get-D365LcsApiConfig]() [Get-D365LcsApiToken]() [Get-D365LcsAssetValidationStatus]() [Get-D365LcsDeploymentStatus]() [Invoke-D365LcsApiRefreshToken]() [Invoke-D365LcsUpload]() [Set-D365LcsApiConfig]() ================================================ FILE: docs/Invoke-D365LcsEnvironmentStart.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365LcsEnvironmentStart ## SYNOPSIS Start a specified environment through LCS. ## SYNTAX ``` Invoke-D365LcsEnvironmentStart [[-ProjectId] ] [[-BearerToken] ] [-EnvironmentId] [[-LcsApiUri] ] [-FailOnErrorMessage] [[-RetryTimeout] ] [-EnableException] [] ``` ## DESCRIPTION Start a specified IAAS environment that is Customer Managed through the LCS API. ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365LcsEnvironmentStart -ProjectId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" ``` This will trigger the environment start operation upon the given environment through the LCS API. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" ### EXAMPLE 2 ``` Invoke-D365LcsEnvironmentStart -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" ``` This will trigger the environment start operation upon the given environment through the LCS API. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 3 ``` Invoke-D365LcsEnvironmentStart -ProjectId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -RetryTimeout "00:01:00" ``` 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. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: 2 Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -EnvironmentId The unique id of the environment that you want to take action upon The Id can be located inside the LCS portal ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Only Customer Managed IAAS environments are supported with this API. Microsoft Managed IAAS environments need to remain online to allow for Microsoft update operations and are not supported with this API. Self-service environments do not have a stop functionality and will not work with this API. Tags: Environment, Start, StartStop, Stop, LCS, Api Author: Mötz Jensen (@Splaxi), Billy Richardson (@richardsondev) ## RELATED LINKS [Get-D365LcsApiConfig]() [Get-D365LcsApiToken]() [Invoke-D365LcsApiRefreshToken]() [Set-D365LcsApiConfig]() [Invoke-D365LcsEnvironmentStop]() ================================================ FILE: docs/Invoke-D365LcsEnvironmentStop.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365LcsEnvironmentStop ## SYNOPSIS Stop a specified environment through LCS. ## SYNTAX ``` Invoke-D365LcsEnvironmentStop [[-ProjectId] ] [[-BearerToken] ] [-EnvironmentId] [[-LcsApiUri] ] [-FailOnErrorMessage] [[-RetryTimeout] ] [-EnableException] [] ``` ## DESCRIPTION Stop a specified IAAS environment that is Customer Managed through the LCS API. ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365LcsEnvironmentStop -ProjectId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" ``` This will trigger the environment stop operation upon the given environment through the LCS API. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" ### EXAMPLE 2 ``` Invoke-D365LcsEnvironmentStop -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" ``` This will trigger the environment stop operation upon the given environment through the LCS API. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 3 ``` Invoke-D365LcsEnvironmentStop -ProjectId 123456789 -EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -RetryTimeout "00:01:00" ``` 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. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The environment is identified by the EnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e", which can be obtained in the LCS portal. All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: 2 Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -EnvironmentId The unique id of the environment that you want to take action upon The Id can be located inside the LCS portal ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Only Customer Managed IAAS environments are supported with this API. Microsoft Managed IAAS environments need to remain online to allow for Microsoft update operations and are not supported with this API. Self-service environments do not have a stop functionality and will not work with this API. Tags: Environment, Stop, StartStop, Start, LCS, Api Author: Mötz Jensen (@Splaxi), Billy Richardson (@richardsondev) ## RELATED LINKS [Get-D365LcsApiConfig]() [Get-D365LcsApiToken]() [Invoke-D365LcsApiRefreshToken]() [Set-D365LcsApiConfig]() [Invoke-D365LcsEnvironmentStart]() ================================================ FILE: docs/Invoke-D365LcsUpload.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365LcsUpload ## SYNOPSIS Upload a file to a LCS project ## SYNTAX ``` Invoke-D365LcsUpload [[-ProjectId] ] [[-BearerToken] ] [-FilePath] [[-FileType] ] [[-Name] ] [[-Filename] ] [[-FileDescription] ] [[-LcsApiUri] ] [-FailOnErrorMessage] [[-RetryTimeout] ] [-EnableException] [] ``` ## DESCRIPTION Upload a file to a LCS project using the API provided by Microsoft ## EXAMPLES ### EXAMPLE 1 ``` 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" ``` This will start the upload of a file to the Asset Library. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The file that will be uploaded is based on the FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip". The file type "Software Deployable Package" determines where inside the Asset Library the file will end up. The name inside the Asset Library is based on the Name "Release-2019-05-05". The file name inside the Asset Library is based on the FileName "Release-2019-05-05.zip". The description inside the Asset Library is based on the FileDescription "Build based on sprint: SuperSprint-1". The request will authenticate with the BearerToken "Bearer JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). ### EXAMPLE 2 ``` Invoke-D365LcsUpload -FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip" -FileType "SoftwareDeployablePackage" -FileName "Release-2019-05-05.zip" ``` This will start the upload of a file to the Asset Library. The file that will be uploaded is based on the FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip". The file type "Software Deployable Package" determines where inside the Asset Library the file will end up. The file name inside the Asset Library is based on the FileName "Release-2019-05-05.zip". All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 3 ``` Invoke-D365LcsUpload -FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip" ``` This will start the upload of a file to the Asset Library. The file that will be uploaded is based on the FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip". All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ### EXAMPLE 4 ``` Invoke-D365LcsUpload -FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip" -RetryTimeout "00:01:00" ``` 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. The file that will be uploaded is based on the FilePath "C:\temp\d365fo.tools\Release-2019-05-05.zip". All default values will come from the configuration available from Get-D365LcsApiConfig. The default values can be configured using Set-D365LcsApiConfig. ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: 2 Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -FilePath Path to the file that you want to upload to the Asset Library on LCS ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -FileType Type of file you want to upload Valid options: "Model" "Process Data Package" "Software Deployable Package" "GER Configuration" "Data Package" "PowerBI Report Model" "E-Commerce Package" "NuGet Package" "Retail Self-Service Package" "Commerce Cloud Scale Unit Extension" Default value is "Software Deployable Package" ```yaml Type: LcsAssetFileType Parameter Sets: (All) Aliases: Accepted values: Model, ProcessDataPackage, SoftwareDeployablePackage, GERConfiguration, DataPackage, PowerBIReportModel, ECommercePackage, NuGetPackage, RetailSelfServicePackage, CommerceCloudScaleUnitExtension Required: False Position: 4 Default value: SoftwareDeployablePackage Accept pipeline input: False Accept wildcard characters: False ``` ### -Name Name to be assigned / shown on LCS ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Filename Filename to be assigned / shown on LCS Often will it require an extension for it to be accepted ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -FileDescription Description to be assigned / shown on LCS ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 8 Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -FailOnErrorMessage Instruct the cmdlet to write logging information to the console, if there is an error message in the response from the LCS endpoint 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 This allows you to implement custom retry / error handling logic ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: 9 Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, Api, AAD, Token Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Get-D365LcsApiConfig]() [Get-D365LcsApiToken]() [Get-D365LcsAssetValidationStatus]() [Get-D365LcsDeploymentStatus]() [Invoke-D365LcsApiRefreshToken]() [Invoke-D365LcsDeployment]() [Set-D365LcsApiConfig]() ================================================ FILE: docs/Invoke-D365ModuleCompile.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365ModuleCompile ## SYNOPSIS Compile a package / module / model ## SYNTAX ``` Invoke-D365ModuleCompile [-Module] [[-OutputDir] ] [[-LogPath] ] [[-MetaDataDir] ] [[-ReferenceDir] ] [[-BinDir] ] [[-XRefSqlServer] ] [[-XRefDbName] ] [-XRefGeneration] [-XRefGenerationOnly] [-ShowOriginalProgress] [-OutputCommandOnly] [] ``` ## DESCRIPTION Compile a package / module / model using the builtin "xppc.exe" executable to compile source code ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365ModuleCompile -Module MyModel ``` This will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package. The default output from the compile will be silenced. If an error should occur, both the standard output and error output will be written to the console / host. ### EXAMPLE 2 ``` Invoke-D365ModuleCompile -Module MyModel -ShowOriginalProgress ``` This will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package. The output from the compile will be written to the console / host. ### EXAMPLE 3 ``` Invoke-D365ModuleCompile -Module MyModel -XRefGeneration ``` This will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package. The default output from the compile will be silenced. The compiler will generate XRef metadata while compiling. If an error should occur, both the standard output and error output will be written to the console / host. ### EXAMPLE 4 ``` Invoke-D365ModuleCompile -Module MyModel -XRefGenerationOnly ``` This will use the default paths and start the xppc.exe with the needed parameters to only generate cross references for the MyModel package. ### EXAMPLE 5 ``` Get-D365Module -ExcludeBinaryModules -InDependencyOrder | Invoke-D365ModuleCompile -XRefGenerationOnly -ShowOriginalProgress ``` This will update all cross references, keeping the assemblies and PDB files unmodified. The output from the compile will be written to the console / host. ## PARAMETERS ### -Module The package to compile ```yaml Type: String Parameter Sets: (All) Aliases: ModuleName Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -OutputDir The path to the folder to save generated artifacts ```yaml Type: String Parameter Sets: (All) Aliases: Output Required: False Position: 2 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath Path where you want to store the log outputs generated from the compiler Also used as the path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 3 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ModuleCompile") Accept pipeline input: False Accept wildcard characters: False ``` ### -MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -ReferenceDir The full path of a folder containing all assemblies referenced from X++ code Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:BinDirTools Accept pipeline input: False Accept wildcard characters: False ``` ### -XRefSqlServer The name of the SQL server where the cross references database is located; the default is "$env:COMPUTERNAME" This parameter is only used for XRefGenerationOnly ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: $env:COMPUTERNAME Accept pipeline input: False Accept wildcard characters: False ``` ### -XRefDbName The name of the cross references database; the default is "DYNAMICSXREFDB" This parameter is only used for XRefGenerationOnly ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 8 Default value: DYNAMICSXREFDB Accept pipeline input: False Accept wildcard characters: False ``` ### -XRefGeneration Instruct the cmdlet to enable the generation of XRef metadata while running the compile ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -XRefGenerationOnly Instruct the cmdlet to only generate XRef metadata while running the compile and not update the assemblies and PDB files ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### [PsCustomObject] ## NOTES Tags: Compile, Model, Servicing, X++ Author: Ievgen Miroshnikov (@IevgenMir) Author: Mötz Jensen (@Splaxi) Author: Frank Hüther (@FrankHuether) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365ModuleFullCompile.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365ModuleFullCompile ## SYNOPSIS Compile a package ## SYNTAX ``` Invoke-D365ModuleFullCompile [-Module] [[-OutputDir] ] [[-LogPath] ] [[-MetaDataDir] ] [[-ReferenceDir] ] [[-BinDir] ] [-ShowOriginalProgress] [-OutputCommandOnly] [] ``` ## 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 ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365ModuleFullCompile -Module MyModel ``` This will use the default paths and start the xppc.exe with the needed parameters to compile MyModel package. The default output from all the different steps will be silenced. ### EXAMPLE 2 ``` Invoke-D365ModuleFullCompile -Module MyModel -ShowOriginalProgress ``` This will use the default paths and start the xppc.exe with the needed parameters to copmile MyModel package. The default output from the different steps will be written to the console / host. ## PARAMETERS ### -Module The package to compile ```yaml Type: String Parameter Sets: (All) Aliases: ModuleName Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -OutputDir The path to the folder to save assemblies ```yaml Type: String Parameter Sets: (All) Aliases: Output Required: False Position: 2 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath Path where you want to store the log outputs generated from the compiler Also used as the path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 3 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ModuleCompile") Accept pipeline input: False Accept wildcard characters: False ``` ### -MetaDataDir The path to the meta data directory for the environment ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -ReferenceDir The full path of a folder containing all assemblies referenced from X++ code ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:BinDirTools Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### [PsCustomObject] ## NOTES Tags: Compile, Model, Servicing Author: Ievgen Miroshnikov (@IevgenMir) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365ModuleLabelGeneration.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365ModuleLabelGeneration ## SYNOPSIS Generate labels for a package / module / model ## SYNTAX ``` Invoke-D365ModuleLabelGeneration [-Module] [[-OutputDir] ] [[-LogPath] ] [[-MetaDataDir] ] [[-ReferenceDir] ] [[-BinDir] ] [-ShowOriginalProgress] [-OutputCommandOnly] [] ``` ## DESCRIPTION Generate labels for a package / module / model using the builtin "labelc.exe" ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365ModuleLabelGeneration -Module MyModel ``` This will use the default paths and start the labelc.exe with the needed parameters to labels from the MyModel package. The default output from the generation process will be silenced. If an error should occur, both the standard output and error output will be written to the console / host. ### EXAMPLE 2 ``` Invoke-D365ModuleLabelGeneration -Module MyModel -ShowOriginalProgress ``` This will use the default paths and start the labelc.exe with the needed parameters to labels from the MyModel package. The output from the compile will be written to the console / host. ## PARAMETERS ### -Module Name of the package that you want to work against ```yaml Type: String Parameter Sets: (All) Aliases: ModuleName Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -OutputDir The path to the folder to save generated artifacts ```yaml Type: String Parameter Sets: (All) Aliases: Output Required: False Position: 2 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath Path where you want to store the log outputs generated from the compiler Also used as the path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 3 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ModuleCompile") Accept pipeline input: False Accept wildcard characters: False ``` ### -MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -ReferenceDir The full path of a folder containing all assemblies referenced from X++ code Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:BinDirTools Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### [PsCustomObject] ## NOTES Tags: Compile, Model, Servicing, Label, Labels Author: Ievgen Miroshnikov (@IevgenMir) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365ModuleReportsCompile.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365ModuleReportsCompile ## SYNOPSIS Generate reports for a package / module / model ## SYNTAX ``` Invoke-D365ModuleReportsCompile [-Module] [[-OutputDir] ] [[-LogPath] ] [[-MetaDataDir] ] [[-ReferenceDir] ] [[-BinDir] ] [-ShowOriginalProgress] [-OutputCommandOnly] [] ``` ## DESCRIPTION Generate reports for a package / module / model using the builtin "ReportsC.exe" ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365ModuleReportsCompile -Module MyModel ``` This will use the default paths and start the ReportsC.exe with the needed parameters to compile the reports from the MyModel package. The default output from the reports compile will be silenced. If an error should occur, both the standard output and error output will be written to the console / host. ### EXAMPLE 2 ``` Invoke-D365ModuleReportsCompile -Module MyModel -ShowOriginalProgress ``` This will use the default paths and start the ReportsC.exe with the needed parameters to compile the reports from the MyModel package. The output from the compile will be written to the console / host. ## PARAMETERS ### -Module Name of the package that you want to work against ```yaml Type: String Parameter Sets: (All) Aliases: ModuleName Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -OutputDir The path to the folder to save generated artifacts ```yaml Type: String Parameter Sets: (All) Aliases: Output Required: False Position: 2 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath Path where you want to store the log outputs generated from the compiler Also used as the path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 3 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ModuleCompile") Accept pipeline input: False Accept wildcard characters: False ``` ### -MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -ReferenceDir The full path of a folder containing all assemblies referenced from X++ code Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:BinDirTools Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### [PsCustomObject] ## NOTES Tags: Compile, Model, Servicing, Report, Reports Author: Ievgen Miroshnikov (@IevgenMir) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365ProcessModule.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365ProcessModule ## SYNOPSIS Process a specific or multiple modules (compile, deploy reports and sync) ## SYNTAX ``` Invoke-D365ProcessModule [-Module] [-ExecuteCompile] [-ExecuteSync] [-ExecuteDeployReports] [[-OutputDir] ] [[-LogPath] ] [[-MetaDataDir] ] [[-ReferenceDir] ] [[-BinDir] ] [-ShowOriginalProgress] [-OutputCommandOnly] [] ``` ## DESCRIPTION Process a specific or multiple modules by invoking the following functions (based on flags) - Invoke-D365ModuleFullCompile function - Publish-D365SsrsReport to deploy the reports of a module - Invoke-D365DBSyncPartial to sync the table and extension elements for module ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365ProcessModule -Module "Application*Adaptor" -ExecuteCompile ``` Retrieve the list of installed packages / modules where the name fits the search "Application*Adaptor". For every value of the list perform the following: * Invoke-D365ModuleFullCompile with the needed parameters to compile current module value package. The default output from all the different steps will be silenced. ### EXAMPLE 2 ``` Invoke-D365ProcessModule -Module "Application*Adaptor" -ExecuteSync ``` Retrieve the list of installed packages / modules where the name fits the search "Application*Adaptor". For every value of the list perform the following: * Invoke-D365DBSyncPartial with the needed parameters to sync current module value table and extension elements. The default output from all the different steps will be silenced. ### EXAMPLE 3 ``` Invoke-D365ProcessModule -Module "Application*Adaptor" -ExecuteDeployReports ``` Retrieve the list of installed packages / modules where the name fits the search "Application*Adaptor". For every value of the list perform the following: * Publish-D365SsrsReport with the required parameters to deploy all reports of current module The default output from all the different steps will be silenced. ### EXAMPLE 4 ``` Invoke-D365ProcessModule -Module "Application*Adaptor" -ExecuteCompile -ExecuteSync -ExecuteDeployReports ``` Retrieve the list of installed packages / modules where the name fits the search "Application*Adaptor". For every value of the list perform the following: * Invoke-D365ModuleFullCompile with the needed parameters to compile current module package. * Invoke-D365DBSyncPartial with the needed parameters to sync current module table and extension elements. * Publish-D365SsrsReport with the required parameters to deploy all reports of current module The default output from all the different steps will be silenced. ## PARAMETERS ### -Module Name of the module that you want to process Accepts wildcards for searching. E.g. -Module "Application*Adaptor" Default value is "*" which will search for all modules ```yaml Type: String Parameter Sets: (All) Aliases: ModuleName Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ExecuteCompile Switch/flag to determine if the compile function should be executed for requested modules ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ExecuteSync Switch/flag to determine if the databasesync function should be executed for requested modules ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ExecuteDeployReports Switch/flag to determine if the deploy reports function should be executed for requested modules ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputDir The path to the folder to save assemblies ```yaml Type: String Parameter Sets: (All) Aliases: Output Required: False Position: 2 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath Path where you want to store the log outputs generated from the compiler Also used as the path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 3 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\ModuleCompile") Accept pipeline input: False Accept wildcard characters: False ``` ### -MetaDataDir The path to the meta data directory for the environment ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -ReferenceDir The full path of a folder containing all assemblies referenced from X++ code ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:MetaDataDir Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:BinDirTools Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Compile, Model, Servicing, Database, Synchronization Author: Jasper Callens - Cegeka ## RELATED LINKS ================================================ FILE: docs/Invoke-D365ReArmWindows.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365ReArmWindows ## SYNOPSIS Invokes the Rearm of Windows license ## SYNTAX ``` Invoke-D365ReArmWindows [-Restart] [] ``` ## DESCRIPTION Function used for invoking the rearm functionality inside Windows ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365ReArmWindows ``` This will re arm the Windows installation if there is any activation retries left ### EXAMPLE 2 ``` Invoke-D365ReArmWindows -Restart ``` This will re arm the Windows installation if there is any activation retries left and restart the computer. ## PARAMETERS ### -Restart Instruct the cmdlet to restart the machine ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365RunbookAnalyzer.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365RunbookAnalyzer ## SYNOPSIS Analyze the runbook ## SYNTAX ### Default (Default) ``` Invoke-D365RunbookAnalyzer -Path [] ``` ### FailedOnlyAsObjects ``` Invoke-D365RunbookAnalyzer -Path [-FailedOnlyAsObjects] [] ``` ### FailedOnly ``` Invoke-D365RunbookAnalyzer -Path [-FailedOnly] [] ``` ## DESCRIPTION Get all the important details from a failed runbook ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365RunbookAnalyzer -Path "C:\DynamicsAX\InstallationRecords\Runbooks\Runbook.xml" ``` This will analyze the Runbook.xml and output all the details about failed steps, the connected error logs and all the unprocessed steps. ### EXAMPLE 2 ``` Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer ``` This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. ### EXAMPLE 3 ``` Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnly ``` This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. The output from Invoke-D365RunbookAnalyzer will only contain failed steps. ### EXAMPLE 4 ``` Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnlyAsObjects ``` This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. The output from Invoke-D365RunbookAnalyzer will only contain failed steps. The output will be formatted as PSCustomObjects, to be used as variables or piping. ### EXAMPLE 5 ``` Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer -FailedOnlyAsObjects | Get-D365RunbookLogFile -Path "C:\Temp\PU35" -OpenInEditor ``` This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. The output from Invoke-D365RunbookAnalyzer will only contain failed steps. The Get-D365RunbookLogFile will open all log files for the failed step. ### EXAMPLE 6 ``` Get-D365Runbook -Latest | Invoke-D365RunbookAnalyzer | Out-File "C:\Temp\d365fo.tools\runbook-analyze-results.xml" ``` This will find the latest runbook file and have it analyzed by the Invoke-D365RunbookAnalyzer cmdlet to output any error details. The output will be saved into the "C:\Temp\d365fo.tools\runbook-analyze-results.xml" file. ### EXAMPLE 7 ``` Get-D365Runbook -Latest | Backup-D365Runbook -Force | Invoke-D365RunbookAnalyzer ``` This will get the latest runbook from the default location. This will backup the file onto the default "c:\temp\d365fo.tools\runbookbackups\". This will start the Runbook Analyzer on the backup file. ## PARAMETERS ### -Path Path to the runbook file that you work against ```yaml Type: String Parameter Sets: (All) Aliases: File Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -FailedOnly Instruct the cmdlet to only output failed steps ```yaml Type: SwitchParameter Parameter Sets: FailedOnly Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -FailedOnlyAsObjects Instruct the cmdlet to only output failed steps as objects ```yaml Type: SwitchParameter Parameter Sets: FailedOnlyAsObjects Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### System.String ## NOTES Tags: Runbook, Servicing, Hotfix, DeployablePackage, Deployable Package, InstallationRecordsDirectory, Installation Records Directory Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365SCDPBundleInstall.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365SCDPBundleInstall ## SYNOPSIS Invoke the SCDPBundleInstall.exe file ## SYNTAX ### InstallOnly (Default) ``` Invoke-D365SCDPBundleInstall [-InstallOnly] [-Path] [[-MetaDataDir] ] [-ShowModifiedFiles] [-ShowProgress] [] ``` ### Tfs ``` Invoke-D365SCDPBundleInstall [[-Command] ] [-Path] [[-MetaDataDir] ] [[-TfsWorkspaceDir] ] [[-TfsUri] ] [-ShowModifiedFiles] [-ShowProgress] [] ``` ## DESCRIPTION A cmdlet that wraps some of the cumbersome work of installing updates / hotfixes into a streamlined process ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365SCDPBundleInstall -Path "c:\temp\HotfixPackageBundle.axscdppkg" -InstallOnly ``` This will install the "HotfixPackageBundle.axscdppkg" into the default PackagesLocalDirectory location on the machine. ## PARAMETERS ### -InstallOnly Instructs the cmdlet to only run the Install option and ignore any TFS / VSTS folders and source control in general Use it when testing an update on a local development machine (VM) / onebox ```yaml Type: SwitchParameter Parameter Sets: InstallOnly Aliases: Required: True Position: 1 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Command The command / job you want the cmdlet to execute Valid options are: Prepare Install Default value is "Prepare" ```yaml Type: String Parameter Sets: Tfs Aliases: Required: False Position: 1 Default value: Prepare Accept pipeline input: False Accept wildcard characters: False ``` ### -Path Path to the update package that you want to install into the environment The cmdlet only supports an already extracted ".axscdppkg" file ```yaml Type: String Parameter Sets: (All) Aliases: File, Hotfix Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: "$Script:MetaDataDir" Accept pipeline input: False Accept wildcard characters: False ``` ### -TfsWorkspaceDir The path to the TFS Workspace directory that you want to work against Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: Tfs Aliases: Required: False Position: 4 Default value: "$Script:MetaDataDir" Accept pipeline input: False Accept wildcard characters: False ``` ### -TfsUri The URI for the TFS Team Site / VSTS Portal that you want to work against Default URI is the one that is configured from inside Visual Studio ```yaml Type: String Parameter Sets: Tfs Aliases: Required: False Position: 5 Default value: "$Script:TfsUri" Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowModifiedFiles Switch to instruct the cmdlet to show all the modified files afterwards ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowProgress Switch to instruct the cmdlet to output progress details while servicing the installation ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Hotfix, Hotfixes, Updates, Prepare, VSTS, axscdppkg Author: Mötz Jensen (@splaxi) Author: Tommy Skaue (@skaue) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365SDPInstall.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365SDPInstall ## SYNOPSIS Install a Software Deployable Package (SDP) ## SYNTAX ### QuickInstall (Default) ``` Invoke-D365SDPInstall [-Path] [[-MetaDataDir] ] [-QuickInstallAll] [[-Step] ] [[-RunbookId] ] [-LogPath ] [-ShowOriginalProgress] [-OutputCommandOnly] [-TopologyFile ] [-UseExistingTopologyFile] [-IncludeFallbackRetailServiceModels] [-Force] [-ForceFallbackServiceModels] [] ``` ### DevInstall ``` Invoke-D365SDPInstall [-Path] [[-MetaDataDir] ] [-DevInstall] [[-Step] ] [[-RunbookId] ] [-LogPath ] [-ShowOriginalProgress] [-OutputCommandOnly] [-TopologyFile ] [-UseExistingTopologyFile] [-IncludeFallbackRetailServiceModels] [-Force] [-ForceFallbackServiceModels] [] ``` ### Manual ``` Invoke-D365SDPInstall [-Path] [[-MetaDataDir] ] [-Command] [[-Step] ] [[-RunbookId] ] [-LogPath ] [-ShowOriginalProgress] [-OutputCommandOnly] [-TopologyFile ] [-UseExistingTopologyFile] [-IncludeFallbackRetailServiceModels] [-Force] [-ForceFallbackServiceModels] [] ``` ### UDEInstall ``` Invoke-D365SDPInstall [-Path] [[-MetaDataDir] ] [[-Step] ] [[-RunbookId] ] [-LogPath ] [-ShowOriginalProgress] [-OutputCommandOnly] [-TopologyFile ] [-UseExistingTopologyFile] [-UnifiedDevelopmentEnvironment] [-IncludeFallbackRetailServiceModels] [-Force] [-ForceFallbackServiceModels] [] ``` ## DESCRIPTION A cmdlet that wraps some of the cumbersome work into a streamlined process. The process for a legacy (i.e. non unified) environment are detailed in the Microsoft documentation here: https://docs.microsoft.com/en-us/dynamics365/unified-operations/dev-itpro/deployment/install-deployable-package ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365SDPInstall -Path "c:\temp\package.zip" -QuickInstallAll ``` This will install the package contained in the c:\temp\package.zip file using a runbook in memory while executing. ### EXAMPLE 2 ``` Invoke-D365SDPInstall -Path "c:\temp\" -DevInstall ``` This will install the extracted package in c:\temp\ using a runbook in memory while executing. 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. ### EXAMPLE 3 ``` Invoke-D365SDPInstall -Path "c:\temp\" -Command SetTopology ``` PS C:\\\> Invoke-D365SDPInstall -Path "c:\temp\" -Command Generate -RunbookId 'MyRunbook' PS C:\\\> Invoke-D365SDPInstall -Path "c:\temp\" -Command Import -RunbookId 'MyRunbook' PS C:\\\> Invoke-D365SDPInstall -Path "c:\temp\" -Command Execute -RunbookId 'MyRunbook' Manual operations that first create Topology XML from current environment, then generate runbook with id 'MyRunbook', then import it and finally execute it. ### EXAMPLE 4 ``` Invoke-D365SDPInstall -Path "c:\temp\" -Command RunAll ``` Create Topology XML from current environment. Using default runbook id 'Runbook' and run all the operations from generate, to import to execute. ### EXAMPLE 5 ``` Invoke-D365SDPInstall -Path "c:\temp\" -Command RerunStep -Step 18 -RunbookId 'MyRunbook' ``` Rerun runbook with id 'MyRunbook' from step 18. ### EXAMPLE 6 ``` Invoke-D365SDPInstall -Path "c:\temp\" -Command SetStepComplete -Step 24 -RunbookId 'MyRunbook' ``` Mark step 24 complete in runbook with id 'MyRunbook' and continue the runbook from the next step. ### EXAMPLE 7 ``` Invoke-D365SDPInstall -Path "c:\temp\" -Command SetTopology -TopologyFile "c:\temp\MyTopology.xml" ``` Update the MyTopology.xml file with all the installed services on the machine. ### EXAMPLE 8 ``` Invoke-D365SDPInstall -Path "c:\temp\" -Command RunAll -TopologyFile "c:\temp\MyTopology.xml" -UseExistingTopologyFile ``` Run all manual steps in one single operation using the MyTopology.xml file. The topology file is not updated. ### EXAMPLE 9 ``` Invoke-D365SDPInstall -Path "c:\temp\" -MetaDataDir "c:\MyRepository\Metadata" -UnifiedDevelopmentEnvironment ``` Install the modules contained in the c:\temp\ directory into the c:\MyRepository\Metadata directory. ### EXAMPLE 10 ``` Invoke-D365SDPInstall -Path "c:\temp\" -Command RunAll -IncludeFallbackRetailServiceModels ``` 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. This fallback list includes the retail service models. Using default runbook id 'Runbook' and run all the operations from generate, to import to execute. ### EXAMPLE 11 ``` Invoke-D365SDPInstall -Path "c:\temp\" -Command RunAll -ForceFallbackServiceModels ``` 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. This fallback list does not include the retail service models. Using default runbook id 'Runbook' and run all the operations from generate, to import to execute. ## PARAMETERS ### -Path Path to the update package that you want to install into the environment The cmdlet supports a path to a zip-file or directory with the unpacked contents. ```yaml Type: String Parameter Sets: (All) Aliases: File, Hotfix Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: "$Script:MetaDataDir" Accept pipeline input: False Accept wildcard characters: False ``` ### -QuickInstallAll Use this switch to let the runbook reside in memory. You will not get a runbook on disc which you can examine for steps ```yaml Type: SwitchParameter Parameter Sets: QuickInstall Aliases: Required: False Position: 4 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -DevInstall Use this when running on developer box without administrator privileges (Run As Administrator) ```yaml Type: SwitchParameter Parameter Sets: DevInstall Aliases: Required: False Position: 4 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Command The command you want the cmdlet to execute when it runs the AXUpdateInstaller.exe Valid options are: SetTopology Generate Import Execute RunAll ReRunStep SetStepComplete Export VersionCheck The default value is "SetTopology" ```yaml Type: String Parameter Sets: Manual Aliases: Required: True Position: 4 Default value: SetTopology Accept pipeline input: False Accept wildcard characters: False ``` ### -Step The step number that you want to work against ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: 0 Accept pipeline input: False Accept wildcard characters: False ``` ### -RunbookId The runbook id of the runbook that you want to work against Default value is "Runbook" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: Runbook Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: Named Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\SdpInstall") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -TopologyFile Provide a custom topology file to use. By default, the cmdlet will use the DefaultTopologyData.xml file in the package directory. ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: DefaultTopologyData.xml Accept pipeline input: False Accept wildcard characters: False ``` ### -UseExistingTopologyFile Use this switch to indicate that the topology file is already updated and should not be updated again. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -UnifiedDevelopmentEnvironment Use this switch to install the package in a Unified Development Environment (UDE). ```yaml Type: SwitchParameter Parameter Sets: UDEInstall Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -IncludeFallbackRetailServiceModels Include fallback retail service models in the topology file This parameter is to support backward compatibility in this scenario: Installing the first update on a local VHD where the information about the installed service models may not be available and where the retail components are installed. More information about this can be found at https://github.com/d365collaborative/d365fo.tools/issues/878 ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Instruct the cmdlet to overwrite the "extracted" folder if it exists Used when the input is a zip file, that will auto extract to a folder named like the zip file. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ForceFallbackServiceModels Force the use of the fallback list of known service model names This parameter supports update scenarios primarily on local VHDs where the information about the installed service models may be incomplete. In such a case, the user receives a warning and a suggestion to use this parameter. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Tommy Skaue (@skaue) Author: Mötz Jensen (@Splaxi) Author: Florian Hopfner (@FH-Inway) Inspired by blogpost http://dev.goshoom.net/en/2016/11/installing-deployable-packages-with-powershell/ ## RELATED LINKS [Invoke-D365SDPInstallUDE]() ================================================ FILE: docs/Invoke-D365SDPInstallUDE.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365SDPInstallUDE ## SYNOPSIS Install a Software Deployable Package (SDP) in a unified development environment ## SYNTAX ``` Invoke-D365SDPInstallUDE [-Path] [-MetaDataDir] [-LogPath ] [-Force] [] ``` ## DESCRIPTION A cmdlet that wraps some of the cumbersome work into a streamlined process. It first checks if the package is a zip file and extracts it if necessary. Then it checks if the package contains the necessary files and modules. Finally, it extracts the module zip files into the metadata directory. ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365SDPInstallUDE -Path "c:\temp\package.zip" -MetaDataDir "c:\MyRepository\Metadata" ``` This will install the modules contained in the c:\temp\package.zip file into the c:\MyRepository\Metadata directory. ## PARAMETERS ### -Path Path to the package that you want to install into the environment The cmdlet supports a path to a zip-file or directory with the unpacked contents. ```yaml Type: String Parameter Sets: (All) Aliases: File, Hotfix Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -MetaDataDir The path to the meta data directory for the environment ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file(s) will be saved ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: Named Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\SdpInstall") Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Instruct the cmdlet to overwrite the "extracted" folder if it exists Used when the input is a zip file, that will auto extract to a folder named like the zip file. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Florian Hopfner (@FH-Inway) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365SeleniumDownload.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365SeleniumDownload ## SYNOPSIS Downloads the Selenium web driver files and deploys them to the specified destinations. ## SYNTAX ``` Invoke-D365SeleniumDownload [-RegressionSuiteAutomationTool] [-PerfSDK] [] ``` ## DESCRIPTION Downloads the Selenium web driver files and deploys them to the specified destinations. ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365SeleniumDownload -RegressionSuiteAutomationTool -PerfSDK ``` This will download the Selenium zip archives and extract the files into both the Regression Suite Automation Tool folder and the PerfSDK folder. ## PARAMETERS ### -RegressionSuiteAutomationTool Switch to specify if the Selenium files need to be installed in the Regression Suite Automation Tool folder. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -PerfSDK Switch to specify if the Selenium files need to be installed in the PerfSDK folder. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Kenny Saelen (@kennysaelen) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365SqlScript.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365SqlScript ## SYNOPSIS Execute a SQL Script or a SQL Command ## SYNTAX ### FilePath ``` Invoke-D365SqlScript [-FilePath] [-DatabaseServer ] [-DatabaseName ] [-SqlUser ] [-SqlPwd ] [-TrustedConnection ] [-EnableException] [-NoPooling] [] ``` ### Command ``` Invoke-D365SqlScript [-Command] [-DatabaseServer ] [-DatabaseName ] [-SqlUser ] [-SqlPwd ] [-TrustedConnection ] [-EnableException] [-NoPooling] [] ``` ## DESCRIPTION Execute a SQL Script or a SQL Command against the D365FO SQL Server database ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365SqlScript -FilePath "C:\temp\d365fo.tools\DeleteUser.sql" ``` This will execute the "C:\temp\d365fo.tools\DeleteUser.sql" against the registered SQL Server on the machine. ### EXAMPLE 2 ``` Invoke-D365SqlScript -Command "DELETE FROM SALESTABLE WHERE RECID = 123456789" ``` This will execute "DELETE FROM SALESTABLE WHERE RECID = 123456789" against the registered SQL Server on the machine. ### EXAMPLE 3 ``` Invoke-D365SqlScript -Command "DELETE FROM SALESTABLE WHERE RECID = 123456789" -NoPooling ``` This will execute "DELETE FROM SALESTABLE WHERE RECID = 123456789" against the registered SQL Server on the machine. It will not use connection pooling. ## PARAMETERS ### -FilePath Path to the file containing the SQL Script that you want executed ```yaml Type: String Parameter Sets: FilePath Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Command SQL command that you want executed ```yaml Type: String Parameter Sets: Command Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -TrustedConnection Switch to instruct the cmdlet whether the connection should be using Windows Authentication or not ```yaml Type: Boolean Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -NoPooling Should the connection use connection pooling or not ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@splaxi) Author: Caleb Blanchard (@daxcaleb) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365SysFlushAodCache.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365SysFlushAodCache ## SYNOPSIS Invoke the SysFlushAos class ## SYNTAX ``` Invoke-D365SysFlushAodCache [[-Url] ] [] ``` ## DESCRIPTION Invoke the runnable class SysFlushAos to clear the AOD cache ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365SysFlushAodCache ``` This will a call against the default URL for the machine and have it execute the SysFlushAOD class ## PARAMETERS ### -Url URL to the Dynamics 365 instance you want to clear the AOD cache on ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365SysRunnerClass.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365SysRunnerClass ## SYNOPSIS Start a browser session that executes SysRunnerClass ## SYNTAX ``` Invoke-D365SysRunnerClass [-ClassName] [[-Company] ] [[-Url] ] [] ``` ## DESCRIPTION Makes it possible to call any runnable class directly from the browser, without worrying about the details ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365SysRunnerClass -ClassName SysFlushAOD ``` Will execute the SysRunnerClass and have it execute the SysFlushAOD class and will run it against the "DAT" (default value) company ### EXAMPLE 2 ``` Invoke-D365SysRunnerClass -ClassName SysFlushAOD -Company "USMF" ``` Will execute the SysRunnerClass and have it execute the SysFlushAOD class and will run it against the "USMF" company ### EXAMPLE 3 ``` Invoke-D365SysRunnerClass -ClassName SysFlushAOD -Url https://Test.cloud.onebox.dynamics.com ``` 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 ## PARAMETERS ### -ClassName The name of the class you want to execute ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Company The company for which you want to execute the class against Default value is: "DAT" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:Company Accept pipeline input: False Accept wildcard characters: False ``` ### -Url The URL you want to execute against Default value is the Fully Qualified Domain Name registered on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:Url Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Invoke-D365TableBrowser.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365TableBrowser ## SYNOPSIS Start a browser session that will show the table browser ## SYNTAX ``` Invoke-D365TableBrowser [-TableName] [[-Company] ] [[-Url] ] [] ``` ## DESCRIPTION Makes it possible to call the table browser for a given table directly from the web browser, without worrying about the details ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365TableBrowser -TableName SalesTable ``` Will open the table browser and show all the records in Sales Table from the "DAT" company (default value). ### EXAMPLE 2 ``` Invoke-D365TableBrowser -TableName SalesTable -Company "USMF" ``` Will open the table browser and show all the records in Sales Table from the "USMF" company. ## PARAMETERS ### -TableName The name of the table you want to see the rows for ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Company The company for which you want to see the data from in the given table Default value is: "DAT" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:Company Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Url The URL you want to execute against Default value is the Fully Qualified Domain Name registered on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:Url Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. ## RELATED LINKS ================================================ FILE: docs/Invoke-D365VisualStudioCompilerResultAnalyzer.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365VisualStudioCompilerResultAnalyzer ## SYNOPSIS Analyze the Visual Studio compiler output log ## SYNTAX ``` Invoke-D365VisualStudioCompilerResultAnalyzer [[-Module] ] [[-OutputPath] ] [-SkipWarnings] [-SkipTasks] [[-PackageDirectory] ] [] ``` ## DESCRIPTION Analyze the Visual Studio compiler output log and generate an excel file contain worksheets per type: Errors, Warnings, Tasks ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365VisualStudioCompilerResultAnalyzer ``` This will analyse all compiler output log files generated from Visual Studio. A result set example: File Filename ---- -------- c:\temp\d365fo.tools\ApplicationCommon-CompilerResults.xlsx ApplicationCommon-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationFoundation-CompilerResults.xlsx ApplicationFoundation-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationPlatform-CompilerResults.xlsx ApplicationPlatform-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationSuite-CompilerResults.xlsx ApplicationSuite-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationWorkspaces-CompilerResults.xlsx ApplicationWorkspaces-CompilerResults.xlsx ### EXAMPLE 2 ``` Invoke-D365VisualStudioCompilerResultAnalyzer -SkipWarnings ``` This will analyse all compiler output log files generated from Visual Studio. It will exclude all warnings from the output. A result set example: File Filename ---- -------- c:\temp\d365fo.tools\ApplicationCommon-CompilerResults.xlsx ApplicationCommon-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationFoundation-CompilerResults.xlsx ApplicationFoundation-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationPlatform-CompilerResults.xlsx ApplicationPlatform-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationSuite-CompilerResults.xlsx ApplicationSuite-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationWorkspaces-CompilerResults.xlsx ApplicationWorkspaces-CompilerResults.xlsx ### EXAMPLE 3 ``` Invoke-D365VisualStudioCompilerResultAnalyzer -SkipTasks ``` This will analyse all compiler output log files generated from Visual Studio. It will exclude all tasks from the output. A result set example: File Filename ---- -------- c:\temp\d365fo.tools\ApplicationCommon-CompilerResults.xlsx ApplicationCommon-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationFoundation-CompilerResults.xlsx ApplicationFoundation-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationPlatform-CompilerResults.xlsx ApplicationPlatform-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationSuite-CompilerResults.xlsx ApplicationSuite-CompilerResults.xlsx c:\temp\d365fo.tools\ApplicationWorkspaces-CompilerResults.xlsx ApplicationWorkspaces-CompilerResults.xlsx ## PARAMETERS ### -Module Name of the module that you want to work against Default value is "*" which will search for all modules ```yaml Type: String Parameter Sets: (All) Aliases: ModuleName Required: False Position: 1 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputPath Path where you want the excel file (xlsx-file) saved to Default value is: "c:\temp\d365fo.tools\" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -SkipWarnings Instructs the cmdlet to skip warnings while analyzing the compiler output log file ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -SkipTasks Instructs the cmdlet to skip tasks while analyzing the compiler output log file ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the directory containing the installed package / module Default path is the same as the AOS service "PackagesLocalDirectory" directory Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Compiler, Build, Errors, Warnings, Tasks Author: Mötz Jensen (@Splaxi) This cmdlet is inspired by the work of "Vilmos Kintera" (twitter: @DAXRunBase) All credits goes to him for showing how to extract these information His blog can be found here: https://www.daxrunbase.com/blog/ The specific blog post that we based this cmdlet on can be found here: https://www.daxrunbase.com/2020/03/31/interpreting-compiler-results-in-d365fo-using-powershell/ The github repository containing the original scrips can be found here: https://github.com/DAXRunBase/PowerShell-and-Azure ## RELATED LINKS ================================================ FILE: docs/Invoke-D365WinRmCertificateRotation.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Invoke-D365WinRmCertificateRotation ## SYNOPSIS Rotate the certificate used for WinRM ## SYNTAX ``` Invoke-D365WinRmCertificateRotation [[-MachineName] ] [] ``` ## DESCRIPTION There is a scenario where you might need to update the certificate that is being used for WinRM on your Tier1 environment 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 ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365WinRmCertificateRotation ``` This will update the certificate that is being used by WinRM. A new certificate is created with the current computer name. The new certificate and its thumbprint will be configured for WinRM to use that going forward. ## PARAMETERS ### -MachineName The DNS / Netbios name of the machine The default value is: "$env:COMPUTERNAME" which translates into the current name of the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $env:COMPUTERNAME Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) We recommend that you do a full restart of the Tier1 environment when done. ## RELATED LINKS ================================================ FILE: docs/New-D365Bacpac.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # New-D365Bacpac ## SYNOPSIS Generate a bacpac file from a database ## SYNTAX ### ExportTier2 (Default) ``` New-D365Bacpac [-ExportModeTier2] [[-DatabaseServer] ] [[-DatabaseName] ] [-SqlUser] [-SqlPwd] [[-NewDatabaseName] ] [[-BacpacFile] ] [[-CustomSqlFile] ] [-DiagnosticFile ] [-ExportOnly] [-MaxParallelism ] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [] ``` ### ExportTier1 ``` New-D365Bacpac [-ExportModeTier1] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-BackupDirectory] ] [[-NewDatabaseName] ] [[-BacpacFile] ] [[-CustomSqlFile] ] [-DiagnosticFile ] [-ExportOnly] [-MaxParallelism ] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [] ``` ## 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 Supports to create a raw bacpac file without prepping. Can be used to automate backup from Tier 2 (MS hosted) environment ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365InstallSqlPackage ``` You should always install the latest version of the SqlPackage.exe, which is used by New-D365Bacpac. This will fetch the latest .Net Core Version of SqlPackage.exe and install it at "C:\temp\d365fo.tools\SqlPackage". ### EXAMPLE 2 ``` New-D365Bacpac -ExportModeTier1 -BackupDirectory c:\Temp\backup\ -NewDatabaseName Testing1 -BacpacFile "C:\Temp\Bacpac\Testing1.bacpac" ``` Will backup the "AXDB" database and restore is as "Testing1" again the localhost SQL Server. Will run the prepping process against the restored database. Will export a bacpac file to "C:\Temp\Bacpac\Testing1.bacpac". Will delete the restored database. It will use trusted connection (Windows authentication) while working against the SQL Server. ### EXAMPLE 3 ``` New-D365Bacpac -ExportModeTier2 -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" -NewDatabaseName Testing1 -BacpacFile C:\Temp\Bacpac\Testing1.bacpac ``` Will create a copy the db database on the dbserver1 in Azure. Will run the prepping process against the copy database. Will export a bacpac file. Will delete the copy database. ### EXAMPLE 4 ``` New-D365Bacpac -ExportModeTier2 -SqlUser User123 -SqlPwd "Password123" -NewDatabaseName Testing1 -BacpacFile "C:\Temp\Bacpac\Testing1.bacpac" ``` Normally used for a Tier-2 export and preparation for Tier-1 import Will create a copy of the registered D365 database on the registered D365 Azure SQL DB instance. Will run the prepping process against the copy database. Will export a bacpac file. Will delete the copy database. ### EXAMPLE 5 ``` New-D365Bacpac -ExportModeTier2 -SqlUser User123 -SqlPwd "Password123" -NewDatabaseName Testing1 -BacpacFile C:\Temp\Bacpac\Testing1.bacpac -ExportOnly ``` Will export a bacpac file. The bacpac should be able to restore back into the database without any preparing because it is coming from the environment from the beginning ### EXAMPLE 6 ``` New-D365Bacpac -ExportModeTier1 -BackupDirectory c:\Temp\backup\ -NewDatabaseName Testing1 -BacpacFile "C:\Temp\Bacpac\Testing1.bacpac" -DiagnosticFile "C:\temp\ExportLog.txt" ``` Will backup the "AXDB" database and restore is as "Testing1" again the localhost SQL Server. Will run the prepping process against the restored database. Will export a bacpac file to "C:\Temp\Bacpac\Testing1.bacpac". Will delete the restored database. It will use trusted connection (Windows authentication) while working against the SQL Server. It will output a diagnostic file to "C:\temp\ExportLog.txt". ### EXAMPLE 7 ``` New-D365Bacpac -ExportModeTier1 -BackupDirectory c:\Temp\backup\ -NewDatabaseName Testing1 -BacpacFile "C:\Temp\Bacpac\Testing1.bacpac" -MaxParallelism 32 ``` Will backup the "AXDB" database and restore is as "Testing1" again the localhost SQL Server. Will run the prepping process against the restored database. Will export a bacpac file to "C:\Temp\Bacpac\Testing1.bacpac". Will delete the restored database. It will use trusted connection (Windows authentication) while working against the SQL Server. It will use 32 connections against the database server while generating the bacpac file. ## PARAMETERS ### -ExportModeTier1 Switch to instruct the cmdlet that the export will be done against a classic SQL Server installation ```yaml Type: SwitchParameter Parameter Sets: ExportTier1 Aliases: Required: True Position: 1 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ExportModeTier2 Switch to instruct the cmdlet that the export will be done against an Azure SQL DB instance ```yaml Type: SwitchParameter Parameter Sets: ExportTier2 Aliases: Required: True Position: 1 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: ExportTier2 Aliases: Required: True Position: 4 Default value: $Script:DatabaseUserName Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: ExportTier1 Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserName Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: ExportTier2 Aliases: Required: True Position: 5 Default value: $Script:DatabaseUserPassword Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: ExportTier1 Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserPassword Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -BackupDirectory The path where to store the temporary backup file when the script needs to handle that ```yaml Type: String Parameter Sets: ExportTier1 Aliases: Required: False Position: 6 Default value: C:\Temp\d365fo.tools\SqlBackups Accept pipeline input: False Accept wildcard characters: False ``` ### -NewDatabaseName The name for the database the script is going to create when doing the restore process ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: "$Script:DatabaseName`_export" Accept pipeline input: False Accept wildcard characters: False ``` ### -BacpacFile The path where you want the cmdlet to store the bacpac file that will be generated ```yaml Type: String Parameter Sets: (All) Aliases: File Required: False Position: 8 Default value: "C:\Temp\d365fo.tools\$DatabaseName.bacpac" Accept pipeline input: False Accept wildcard characters: False ``` ### -CustomSqlFile The path to a custom sql server script file that you want executed against the database before it is exported ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 9 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -DiagnosticFile Path to where you want the export to output a diagnostics file to assist you in troubleshooting the export ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ExportOnly Switch to instruct the cmdlet to either just create a dump bacpac file or run the prepping process first ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -MaxParallelism Sets SqlPackage.exe's degree of parallelism for concurrent operations running against a database. The default value is 8. ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: 8 Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES The cmdlet supports piping and can be used in advanced scenarios. See more on github and the wiki pages. Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/New-D365CAReport.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # New-D365CAReport ## SYNOPSIS Generate the Customization's Analysis Report (CAR) ## SYNTAX ``` New-D365CAReport [[-OutputPath] ] [-Module] [-Model] [-SuffixWithModule] [[-BinDir] ] [[-MetaDataDir] ] [[-XmlLog] ] [-PackagesRoot] [[-LogPath] ] [-ShowOriginalProgress] [-OutputCommandOnly] [] ``` ## DESCRIPTION A cmdlet that wraps some of the cumbersome work into a streamlined process ## EXAMPLES ### EXAMPLE 1 ``` New-D365CAReport -module "ApplicationSuite" -model "MyOverLayerModel" ``` This will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module. It will use the default value for the OutputPath parameter, which is "c:\temp\d365fo.tools\CAReport.xlsx". ### EXAMPLE 2 ``` New-D365CAReport -OutputPath "c:\temp\CAReport.xlsx" -module "ApplicationSuite" -model "MyOverLayerModel" ``` This will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module. It will use the "c:\temp\CAReport.xlsx" value for the OutputPath parameter. ### EXAMPLE 3 ``` New-D365CAReport -module "ApplicationSuite" -model "MyOverLayerModel" -SuffixWithModule ``` This will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module. It will use the default value for the OutputPath parameter, which is "c:\temp\d365fo.tools\CAReport.xlsx". It will append the module name to the desired output file, which will then be "c:\temp\d365fo.tools\CAReport-ApplicationSuite.xlsx". ### EXAMPLE 4 ``` New-D365CAReport -OutputPath "c:\temp\CAReport.xlsx" -module "ApplicationSuite" -model "MyOverLayerModel" -PackagesRoot ``` This will generate a CAR report against MyOverLayerModel in the ApplicationSuite Module. It will use the binary metadata to look for the module and model. It will use the "c:\temp\CAReport.xlsx" value for the OutputPath parameter. ## PARAMETERS ### -OutputPath Path where you want the CAR file (xlsx-file) saved to Default value is: "c:\temp\d365fo.tools\CAReport.xlsx" ```yaml Type: String Parameter Sets: (All) Aliases: Path, File Required: False Position: 1 Default value: (Join-Path $Script:DefaultTempPath "CAReport.xlsx") Accept pipeline input: False Accept wildcard characters: False ``` ### -Module Name of the Module to analyse ```yaml Type: String Parameter Sets: (All) Aliases: ModuleName, Package Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Model Name of the Model to analyse ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -SuffixWithModule Instruct the cmdlet to append the module name as a suffix to the desired output file name ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: "$Script:PackageDirectory\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: "$Script:MetaDataDir" Accept pipeline input: False Accept wildcard characters: False ``` ### -XmlLog Path where you want to store the Xml log output generated from the best practice analyser ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: (Join-Path $Script:DefaultTempPath "BPCheckLogcd.xml") Accept pipeline input: False Accept wildcard characters: False ``` ### -PackagesRoot Instructs the cmdlet to use binary metadata ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 7 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\CAReport") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Tommy Skaue (@Skaue) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/New-D365EntraIntegration.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # New-D365EntraIntegration ## SYNOPSIS Enable the Microsoft Entra ID integration on a cloud hosted environment (CHE). ## SYNTAX ### NewCertificate (Default) ``` New-D365EntraIntegration -ClientId [-CertificateName ] [-CertificateExpirationYears ] [-NewCertificateFile ] [-NewCertificatePrivateKeyFile ] [-CertificatePassword ] [-Force] [-WhatIf] [-Confirm] [] ``` ### ExistingCertificate ``` New-D365EntraIntegration -ClientId -ExistingCertificateFile [-ExistingCertificatePrivateKeyFile ] [-CertificatePassword ] [-Force] [-WhatIf] [-Confirm] [] ``` ## 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. The integration can either be enabled with an existing certificate or a new self-signed certificate can be created. 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. The steps executed are: - 1) Create a self-signed certificate and save it to Desktop or use a provided certificate. - 2) Install the certificate to the "LocalMachine" certificate store. - 3) Grant NetworkService READ permission to the certificate (only on cloud-hosted environments). - 4) Update the web.config with the application ID and the thumbprint of the certificate. - 5) Add the application registration to the WIF config. - 6) Clear cached LCS configuration in AxDB. - 7) Restart the IIS service. To execute the steps, the id of an Azure application must be provided. The application must have the following API permissions: - Dynamics ERP - This permission is required to access finance and operations environments. - Microsoft Graph (User.Read.All and Group.Read.All permissions of the Application type). - Dynamics Lifecylce service (permission of type Delegated) The URL of the finance and operations environment must also be added to the RedirectURI in the Authentication section of the Azure application. Finally, after running the cmdlet, if a new certificate was created, it must be uploaded to the Azure application. ## EXAMPLES ### EXAMPLE 1 ``` New-D365EntraIntegration -ClientId e70cac82-6a7c-4f9e-a8b9-e707b961e986 ``` Enables the Entra ID integration with a new self-signed certificate named "CHEAuth" which expires after 2 years. ### EXAMPLE 2 ``` New-D365EntraIntegration -ClientId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -CertificateName "SelfsignedCert" ``` Enables the Entra ID integration with a new self-signed certificate with the name "Selfsignedcert" that expires after 2 years. ### EXAMPLE 3 ``` New-D365EntraIntegration -AppId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -CertificateName "SelfsignedCert" -CertificateExpirationYears 1 ``` Enables the Entra ID integration with a new self-signed certificate with the name "SelfsignedCert" that expires after 1 year. ### EXAMPLE 4 ``` $securePassword = Read-Host -AsSecureString -Prompt "Enter the certificate password" ``` PS C:\\\> New-D365EntraIntegration -AppId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -CertificatePassword $securePassword 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. The certificate file and the private key file are saved to the Desktop of the current user. ### EXAMPLE 5 ``` $securePassword = Read-Host -AsSecureString -Prompt "Enter the certificate password" ``` PS C:\\\> New-D365EntraIntegration -AppId e70cac82-6a7c-4f9e-a8b9-e707b961e986 -ExistingCertificateFile "C:\Temp\SelfsignedCert.cer" -ExistingCertificatePrivateKeyFile "C:\Temp\SelfsignedCert.pfx" -CertificatePassword $securePassword 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. ## PARAMETERS ### -ClientId The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal. It is assumed that an application with this id already exists in Azure. ```yaml Type: String Parameter Sets: (All) Aliases: AppId Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ExistingCertificateFile The path to a certificate file. If this parameter is provided, the cmdlet will not create a new certificate. ```yaml Type: String Parameter Sets: ExistingCertificate Aliases: Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ExistingCertificatePrivateKeyFile The path to a certificate private key file. If this parameter is not provided, the certificate can be installed to the certificate store, but the NetworkService cannot be granted READ permission. ```yaml Type: String Parameter Sets: ExistingCertificate Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -CertificateName The name for the certificate. By default, it is named "CHEAuth". ```yaml Type: String Parameter Sets: NewCertificate Aliases: Required: False Position: Named Default value: CHEAuth Accept pipeline input: False Accept wildcard characters: False ``` ### -CertificateExpirationYears The number of years the certificate is valid. By default, it is valid for 2 years. ```yaml Type: Int32 Parameter Sets: NewCertificate Aliases: Required: False Position: Named Default value: 2 Accept pipeline input: False Accept wildcard characters: False ``` ### -NewCertificateFile The path to the certificate file that will be created. By default, it is created on the Desktop of the current user. ```yaml Type: String Parameter Sets: NewCertificate Aliases: Required: False Position: Named Default value: "$env:USERPROFILE\Desktop\$CertificateName.cer" Accept pipeline input: False Accept wildcard characters: False ``` ### -NewCertificatePrivateKeyFile The path to the certificate private key file that will be created. By default, it is created on the Desktop of the current user. ```yaml Type: String Parameter Sets: NewCertificate Aliases: Required: False Position: Named Default value: "$env:USERPROFILE\Desktop\$CertificateName.pfx" Accept pipeline input: False Accept wildcard characters: False ``` ### -CertificatePassword The password for the certificate private key file. If not provided when creating a new certificate, no private key file will be created. If not provided when using an existing certificate, the private key file cannot be installed. ```yaml Type: SecureString Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Force 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. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf Executes the cmdlet until the first operation that would change the state of the system, without executing that operation. Subsequent operations are likely to fail. This is currently not fully implemented and should not be used. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Confirm Prompts for confirmation before each operation of the cmdlet that changes the state of the system. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### If a new certificate is created, the certificate file is placed on the Desktop of the current user. ### It must be uploaded to the Azure Application. ## NOTES Test-D365EntraIntegration can be used to validate an entra integration. Author: Øystein Brenna (@oysbre) Author: Florian Hopfner (@FH-Inway) ## RELATED LINKS ================================================ FILE: docs/New-D365ISVLicense.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # New-D365ISVLicense ## SYNOPSIS Create a license deployable package ## SYNTAX ``` New-D365ISVLicense [-LicenseFile] [-Path ] [-OutputPath ] [] ``` ## DESCRIPTION Create a deployable package with a license file inside ## EXAMPLES ### EXAMPLE 1 ``` New-D365ISVLicense -LicenseFile "C:\temp\ISVLicenseFile.txt" ``` This will take the "C:\temp\ISVLicenseFile.txt" file and locate the "ImportISVLicense.zip" template file under the "PackagesLocalDirectory\bin\CustomDeployablePackage\". It will extract the "ImportISVLicense.zip", load the ISVLicenseFile.txt and compress (zip) the files into a deployable package. The package will be exported to "C:\temp\d365fo.tools\ISVLicense.zip" ## PARAMETERS ### -LicenseFile Path to the license file that you want to have inside a deployable package ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Path Path to the template zip file for creating a deployable package with a license file Default path is the same as the aos service "PackagesLocalDirectory\bin\CustomDeployablePackage\ImportISVLicense.zip" ```yaml Type: String Parameter Sets: (All) Aliases: Template Required: False Position: Named Default value: "$Script:BinDirTools\CustomDeployablePackage\ImportISVLicense.zip" Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputPath Path where you want the generated deployable package stored Default value is: "C:\temp\d365fo.tools\ISVLicense.zip" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: C:\temp\d365fo.tools\ISVLicense.zip Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@splaxi) Author: Szabolcs Eötvös Author: Florian Hopfner (@FH-Inway) ## RELATED LINKS ================================================ FILE: docs/New-D365ModuleToRemove.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # New-D365ModuleToRemove ## SYNOPSIS Create a new ModuleToRemove.txt file ## SYNTAX ``` New-D365ModuleToRemove [-Path] [-Modules] [] ``` ## DESCRIPTION Create a new ModuleToRemove.txt file based on a list of module names ## EXAMPLES ### EXAMPLE 1 ``` New-D365ModuleToRemove -Path C:\Temp -Modules "MyRemovedModule1","MySecondRemovedModule" ``` This will create a new ModuleToRemove.txt file and fill in "MyRemovedModule1" and "MySecondRemovedModule" as the modules to remove. The new file is stored at "C:\Temp\ModuleToRemove.txt" ### EXAMPLE 2 ``` New-D365ModuleToRemove -Path C:\Temp -Modules "MyRemovedModule1","MySecondRemovedModule" | Add-D365ModuleToRemove -DeployablePackage C:\Temp\DeployablePackage.zip ``` 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. ## PARAMETERS ### -Path Path to the ModuleToRemove.txt file ```yaml Type: String Parameter Sets: (All) Aliases: Folder Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Modules The array with all the module names that you want to fill into the ModuleToRemove.txt file ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Florian Hopfner (@FH-Inway) ## RELATED LINKS [Add-D365ModuleToRemove]() ================================================ FILE: docs/New-D365TopologyFile.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # New-D365TopologyFile ## SYNOPSIS Create a new topology file ## SYNTAX ``` New-D365TopologyFile [-Path] [-Services] [-NewPath] [] ``` ## DESCRIPTION Build a new topology file based on a template and update the ServiceModelList ## EXAMPLES ### EXAMPLE 1 ``` New-D365TopologyFile -Path C:\Temp\DefaultTopologyData.xml -Services "ALMService","AOSService","BIService" -NewPath C:\temp\CurrentTopology.xml ``` This will read the "DefaultTopologyData.xml" file and fill in "ALMService","AOSService" and "BIService" as the services in the ServiceModelList tag. The new file is stored at "C:\temp\CurrentTopology.xml" ### EXAMPLE 2 ``` $Services = @(Get-D365InstalledService | ForEach-Object {$_.Servicename}) ``` PS C:\\\> New-D365TopologyFile -Path C:\Temp\DefaultTopologyData.xml -Services $Services -NewPath C:\temp\CurrentTopology.xml This will get all the services already installed on the machine. Afterwards the list is piped to New-D365TopologyFile where all services are import into the new topology file that is stored at "C:\temp\CurrentTopology.xml" ## PARAMETERS ### -Path Path to the template topology file ```yaml Type: String Parameter Sets: (All) Aliases: File Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Services The array with all the service names that you want to fill into the topology file ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -NewPath Path to where you want to save the new file after it has been created ```yaml Type: String Parameter Sets: (All) Aliases: NewFile Required: True Position: 4 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Publish-D365SsrsReport.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Publish-D365SsrsReport ## SYNOPSIS Deploy Report ## SYNTAX ``` Publish-D365SsrsReport [[-Module] ] [[-ReportName] ] [[-LogFile] ] [[-PackageDirectory] ] [[-ToolsBasePath] ] [[-ReportServerIp] ] [] ``` ## DESCRIPTION Deploy SSRS Report to SQL Server Reporting Services ## EXAMPLES ### EXAMPLE 1 ``` Publish-D365SsrsReport -Module ApplicationSuite -ReportName TaxVatRegister.Report ``` This will deploy the report which is named "TaxVatRegister.Report". The cmdlet will look for the report inside the ApplicationSuite module. The cmdlet will be using the default 127.0.0.1 while deploying the report. ### EXAMPLE 2 ``` Publish-D365SsrsReport -Module ApplicationSuite -ReportName * ``` This will deploy the all reports from the ApplicationSuite module. The cmdlet will be using the default 127.0.0.1 while deploying the report. ## PARAMETERS ### -Module Name of the module that you want to works against Accepts an array of strings Default value is "*" and will work against all modules loaded on the machine ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -ReportName Name of the report that you want to deploy Default value is "*" and will deploy all reports from the module(s) that you speficied ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: * Accept pipeline input: False Accept wildcard characters: False ``` ### -LogFile Path to the file that should contain the logging information Default value is "c:\temp\d365fo.tools\AxReportDeployment.log" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: (Join-Path $Script:DefaultTempPath "AxReportDeployment.log") Accept pipeline input: False Accept wildcard characters: False ``` ### -PackageDirectory Path to the PackagesLocalDirectory Default path is the same as the AOS Service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### -ToolsBasePath Base path to the folder containing the needed PowerShell manifests that the cmdlet utilizes Default path is the same as the AOS Service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### -ReportServerIp IP Address of the server that has SQL Reporting Services installed Default value is "127.0.01" ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: 127.0.0.1 Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### [PsCustomObject] ## NOTES Tags: SSRS, Report, Reports, Deploy, Publish Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Publish-D365WebResources.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Publish-D365WebResources ## SYNOPSIS Deploy web resources ## SYNTAX ``` Publish-D365WebResources [[-PackageDirectory] ] [[-AosServiceWebRootPath] ] [] ``` ## DESCRIPTION Deploys the Dynamics 365 for Finance and Operations web resources to the AOS service web root path. ## EXAMPLES ### EXAMPLE 1 ``` Publish-D365WebResources ``` This will deploy the web resources to the AOS service web root path. ## PARAMETERS ### -PackageDirectory Path to the package directory containing the web resources. ```yaml Type: PathDirectoryParameter Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:PackageDirectory Accept pipeline input: False Accept wildcard characters: False ``` ### -AosServiceWebRootPath Path to the AOS service web root path. ```yaml Type: PathDirectoryParameter Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:AOSPath Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Florian Hopfner (@FH-Inway) ## RELATED LINKS ================================================ FILE: docs/Register-D365AzureStorageConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Register-D365AzureStorageConfig ## SYNOPSIS Register Azure Storage Configurations ## SYNTAX ``` Register-D365AzureStorageConfig [[-ConfigStorageLocation] ] [] ``` ## DESCRIPTION Register all Azure Storage Configurations ## EXAMPLES ### EXAMPLE 1 ``` Register-D365AzureStorageConfig -ConfigStorageLocation "System" ``` This will store all Azure Storage Configurations as defaults for all users on the machine. ## PARAMETERS ### -ConfigStorageLocation Parameter used to instruct where to store the configuration objects The default value is "User" and this will store all configuration for the active user Valid options are: "User" "System" "System" will store the configuration as default for all users, so they can access the configuration objects ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: User Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Configuration, Azure, Storage Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Remove-D365BroadcastMessageConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Remove-D365BroadcastMessageConfig ## SYNOPSIS Remove broadcast message configuration ## SYNTAX ``` Remove-D365BroadcastMessageConfig [-Name] [-Temporary] [] ``` ## DESCRIPTION Remove a broadcast message configuration from the configuration store ## EXAMPLES ### EXAMPLE 1 ``` Remove-D365BroadcastMessageConfig -Name "UAT" ``` This will remove the broadcast message configuration name "UAT" from the machine. ## PARAMETERS ### -Name Name of the broadcast message configuration you want to remove from the configuration store ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Temporary Instruct the cmdlet to only temporarily remove the broadcast message configuration from the configuration store ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Servicing, Broadcast, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Add-D365BroadcastMessageConfig]() [Clear-D365ActiveBroadcastMessageConfig]() [Get-D365ActiveBroadcastMessageConfig]() [Get-D365BroadcastMessageConfig]() [Send-D365BroadcastMessage]() [Set-D365ActiveBroadcastMessageConfig]() ================================================ FILE: docs/Remove-D365Database.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Remove-D365Database ## SYNOPSIS Removes a database ## SYNTAX ``` Remove-D365Database [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [-EnableException] [-Force] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION Removes a database. By default, if no other database is specified, the AxDB database will be removed. ## EXAMPLES ### EXAMPLE 1 ``` Remove-D365Database ``` This will remove the "AxDB" database from the default SQL Server instance that is registered on the machine. ### EXAMPLE 2 ``` Remove-D365Database -DatabaseName "ExportClone" ``` This will remove the "ExportClone" from the default SQL Server instance that is registered on the machine. ## PARAMETERS ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Force This parameter will suppress the confirmation prompt. It can be used as an alternative to -Confirm:$false ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf This parameter will simulate the actions of the command. No changes will be made. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Confirm This parameter will prompt you for confirmation before executing steps of the command that have a medium impact. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) Author: Florian Hopfner (@FH-Inway) ## RELATED LINKS ================================================ FILE: docs/Remove-D365LcsAssetFile.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Remove-D365LcsAssetFile ## SYNOPSIS Delete asset from the LCS project Asset Library ## SYNTAX ``` Remove-D365LcsAssetFile [[-ProjectId] ] [-AssetId] [[-BearerToken] ] [[-LcsApiUri] ] [[-RetryTimeout] ] [-EnableException] [] ``` ## DESCRIPTION Delete asset from the LCS project Asset Library ## EXAMPLES ### EXAMPLE 1 ``` Remove-D365LcsAssetFile -ProjectId 123456789 -BearerToken "JldjfafLJdfjlfsalfd..." -LcsApiUri "https://lcsapi.lcs.dynamics.com" -AssetId "812bcb0e-23fb-476d-8a92-985f20a704b9" ``` This will delete the Asset file from the LCS Asset Library. The LCS project is identified by the ProjectId 123456789, which can be obtained in the LCS portal. The request will authenticate with the BearerToken "JldjfafLJdfjlfsalfd...". The http request will be going to the LcsApiUri "https://lcsapi.lcs.dynamics.com" (NON-EUROPE). ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS Default value can be configured using Set-D365LcsApiConfig ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:LcsApiProjectId Accept pipeline input: False Accept wildcard characters: False ``` ### -AssetId LCS Id of the file that you are looking for ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Token Required: False Position: 3 Default value: $Script:LcsApiBearerToken Accept pipeline input: False Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" Default value can be configured using Set-D365LcsApiConfig ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:LcsApiLcsApiUri Accept pipeline input: False Accept wildcard characters: False ``` ### -RetryTimeout The retry timeout, before the cmdlet should quit retrying based on the 429 status code Needs to be provided in the timspan notation: "hh:mm:ss" hh is the number of hours, numerical notation only mm is the number of minutes ss is the numbers of seconds Each section of the timeout has to valid, e.g. hh can maximum be 23 mm can maximum be 59 ss can maximum be 59 Not setting this parameter will result in the cmdlet to try for ever to handle the 429 push back from the endpoint ```yaml Type: TimeSpan Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: 00:00:00 Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Oleksandr Nikolaiev (@onikolaiev) ## RELATED LINKS [Get-D365LcsApiConfig]() [Get-D365LcsApiToken]() [Invoke-D365LcsApiRefreshToken]() [Set-D365LcsApiConfig]() [Remove-LcsAssetFile]() ================================================ FILE: docs/Remove-D365Model.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Remove-D365Model ## SYNOPSIS Remove a model from Dynamics 365 for Finance & Operations ## SYNTAX ``` Remove-D365Model [-Model] [[-BinDir] ] [[-MetaDataDir] ] [-DeleteFolders] [-ShowOriginalProgress] [-OutputCommandOnly] [] ``` ## DESCRIPTION Remove a model from a Dynamics 365 for Finance & Operations environment ## EXAMPLES ### EXAMPLE 1 ``` Remove-D365Model -Model CustomModelName ``` This will remove the "CustomModelName" model from the D365FO environment. It will NOT remove the folders inside the PackagesLocalDirectory location. ### EXAMPLE 2 ``` Remove-D365Model -Model CustomModelName -DeleteFolders ``` This will remove the "CustomModelName" model from the D365FO environment. It will remove the folders inside the PackagesLocalDirectory location. This is helpful when dealing with source control and you want to remove the model entirely. ## PARAMETERS ### -Model Name of the model that you want to work against ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -BinDir The path to the bin directory for the environment Default path is the same as the AOS service PackagesLocalDirectory\bin Default value is fetched from the current configuration on the machine ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$Script:PackageDirectory\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### -MetaDataDir The path to the meta data directory for the environment Default path is the same as the aos service PackagesLocalDirectory ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: "$Script:MetaDataDir" Accept pipeline input: False Accept wildcard characters: False ``` ### -DeleteFolders Instruct the cmdlet to delete the model folder This is useful when you are trying to clean up the folders in your source control / branch ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: ModelUtil, Axmodel, Model, Remove, Delete, Source Control, Vsts, Azure DevOps Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Remove-D365User.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Remove-D365User ## SYNOPSIS Delete an user from the environment ## SYNTAX ``` Remove-D365User [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [-Email] [] ``` ## DESCRIPTION Deletes the user from the database, including security configuration ## EXAMPLES ### EXAMPLE 1 ``` Remove-D365User -Email "Claire@contoso.com" ``` This will move all security and user details from the user with the email address "Claire@contoso.com" ### EXAMPLE 2 ``` Get-D365User -Email *contoso.com | Remove-D365User ``` This will first get all users from the database that matches the *contoso.com search and pipe their emails to Remove-D365User for it to delete them. ## PARAMETERS ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -Email The search string to select which user(s) should be updated. You have to specific the explicit email address of the user you want to remove The cmdlet will not be able to delete the ADMIN user, this is to prevent you from being locked out of the system. ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 6 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Rename-D365ComputerName.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Rename-D365ComputerName ## SYNOPSIS Function for renaming computer. Renames Computer and changes the SSRS Configration ## SYNTAX ``` Rename-D365ComputerName [-NewName] [[-SSRSReportDatabase] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [[-LogPath] ] [-ShowOriginalProgress] [-OutputCommandOnly] [-EnableException] [] ``` ## DESCRIPTION When doing development on-prem, there is as need for changing the Computername. Function both changes Computername and SSRS Configuration ## EXAMPLES ### EXAMPLE 1 ``` Rename-D365ComputerName -NewName "Demo-8.1" -SSRSReportDatabase "ReportServer" ``` This will rename the local machine to the "Demo-8.1" as the new Windows machine name. It will update the registration inside the SQL Server Reporting Services configuration to handle the new name of the machine. ## PARAMETERS ### -NewName The new name for the computer ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -SSRSReportDatabase Name of the SSRS reporting database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: DynamicsAxReportServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -LogPath The path where the log file(s) will be saved When running without the ShowOriginalProgress parameter, the log files will be the standard output and the error output from the underlying tool executed ```yaml Type: String Parameter Sets: (All) Aliases: LogDir Required: False Position: 7 Default value: $(Join-Path -Path $Script:DefaultTempPath -ChildPath "Logs\RsConfig") Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputCommandOnly Instruct the cmdlet to only output the command that you would have to execute by hand Will include full path to the executable and the needed parameters based on your selection ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Rename-D365Instance.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Rename-D365Instance ## SYNOPSIS Rename as D365FO Demo/Dev box ## SYNTAX ``` Rename-D365Instance [-NewName] [[-AosServiceWebRootPath] ] [[-IISServerApplicationHostConfigFile] ] [[-HostsFile] ] [[-BackupExtension] ] [[-MRConfigFile] ] [] ``` ## DESCRIPTION The Rename function, changes the config values used by a D365FO dev box for identifying its name. Standard it is called 'usnconeboxax1aos' ## EXAMPLES ### EXAMPLE 1 ``` Rename-D365Instance -NewName "Demo1" ``` This will rename the D365 for Finance & Operations instance to "Demo1". This IIS will be restarted while doing it. ## PARAMETERS ### -NewName The new name wanted for the D365FO instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -AosServiceWebRootPath Path to the webroot folder for the AOS service 'Default value : C:\AOSService\Webroot ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:AOSPath Accept pipeline input: False Accept wildcard characters: False ``` ### -IISServerApplicationHostConfigFile Path to the IISService Application host file, \[Where the binding configurations is stored\] 'Default value : C:\Windows\System32\inetsrv\Config\applicationHost.config' ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:IISHostFile Accept pipeline input: False Accept wildcard characters: False ``` ### -HostsFile Place of the host file on the current system \[Local DNS record\] ' Default value C:\Windows\System32\drivers\etc\hosts' ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:Hosts Accept pipeline input: False Accept wildcard characters: False ``` ### -BackupExtension Backup name for all the files that are changed ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: Bak Accept pipeline input: False Accept wildcard characters: False ``` ### -MRConfigFile Path to the Financial Reporter (Management Reporter) configuration file ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:MRConfigFile Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) The function restarts the IIS Service. Elevated privileges are required. ## RELATED LINKS ================================================ FILE: docs/Repair-D365BacpacModelFile.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Repair-D365BacpacModelFile ## SYNOPSIS Repair a bacpac model file ## SYNTAX ``` Repair-D365BacpacModelFile [-Path] [[-OutputPath] ] [[-PathRepairSimple] ] [[-PathRepairQualifier] ] [[-PathRepairReplace] ] [-KeepFiles] [-Force] [] ``` ## 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 ## EXAMPLES ### EXAMPLE 1 ``` Repair-D365BacpacModelFile -Path C:\Temp\Base.xml -PathRepairSimple '' -PathRepairQualifier '' -PathRepairReplace 'C:\Temp\RepairBacpac.Replace.Custom.json' ``` This will only process the Replace section, as the other repair paths are empty - indicating to skip them. It will load the instructions from the 'C:\Temp\RepairBacpac.Replace.Custom.json' file and run those in the Replace section. ### EXAMPLE 2 ``` Repair-D365BacpacModelFile -Path C:\Temp\Base.xml -KeepFiles -Force ``` This will process all repair sections. It will keep the files in the temporary work directory, for the user to analyze the files further. It will Force overwrite the output file, if it exists already. ## PARAMETERS ### -Path Path to the bacpac model file that you want to work against ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputPath Path to where the repaired model file should be placed The default value is going to create a file next to the Path (input) file, with the '-edited' name appended to it ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -PathRepairSimple Path to the json file, that contains all the instructions to be executed in the "Simple" section The default json file is part of the module, and can be located with the below command: explorer.exe $(Join-Path -Path $(Split-Path -Path (Get-Module d365fo.tools -ListAvailable)\[0\].Path -Parent) -ChildPath "internal\misc") - Look for the "RepairBacpac.Simple.json" file 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 Simple means, that we can remove complex elements, based on some basic logic. E.g. { "Search": "*\*" } "*\*" - we know when to stop. \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: "$script:ModuleRoot\internal\misc\RepairBacpac.Simple.json" Accept pipeline input: False Accept wildcard characters: False ``` ### -PathRepairQualifier Path to the json file, that contains all the instructions to be executed in the "Qualifier" section The default json file is part of the module, and can be located with the below command: explorer.exe $(Join-Path -Path $(Split-Path -Path (Get-Module d365fo.tools -ListAvailable)\[0\].Path -Parent) -ChildPath "internal\misc") - Look for the "RepairBacpac.Qualifier.json" file 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 Qualifier means, that we can remove complex elements, based on some basic logic. E.g. { "Search": "*\*", "Qualifier": "*\*" } "*\*" can identify below, "*\*" - we know when to stop. \ \ \ \ \ \ \ \ \ \ \ \ ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: "$script:ModuleRoot\internal\misc\RepairBacpac.Qualifier.json" Accept pipeline input: False Accept wildcard characters: False ``` ### -PathRepairReplace Path to the json file, that contains all the instructions to be executed in the "Replace" section The default json file is part of the module, and can be located with the below command: explorer.exe $(Join-Path -Path $(Split-Path -Path (Get-Module d365fo.tools -ListAvailable)\[0\].Path -Parent) -ChildPath "internal\misc") - Look for the "RepairBacpac.Replace.json" file 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 Replace means, that we can replace/remove strings, based on some basic logic. E.g. { "Search": "\", "Replace": "" } "\" can identify below, and "" is the value we want to replace with it. \ ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: "$script:ModuleRoot\internal\misc\RepairBacpac.Replace.json" Accept pipeline input: False Accept wildcard characters: False ``` ### -KeepFiles Instruct the cmdlet to keep the files from the repair process 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 Use it while you evolve/develop your instructions, but remove it from ANY full automation scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Instruct the cmdlet to overwrite the file specified in the OutputPath if it already exists ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) Author: Florian Hopfner (@FH-Inway) 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. This cmdlet is inspired by the work of "Brad Bateman" (github: @batetech) His github profile can be found here: https://github.com/batetech Florian Hopfner did a gist implementation, which has been used as the foundation for this implementation The original gist is: https://gist.github.com/FH-Inway/f485c720b43b72bffaca5fb6c094707e His github profile can be found here: https://github.com/FH-Inway ## RELATED LINKS ================================================ FILE: docs/Restart-D365Environment.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Restart-D365Environment ## SYNOPSIS Restart the different services ## SYNTAX ### Default (Default) ``` Restart-D365Environment [[-ComputerName] ] [-All] [-Kill] [-ShowOriginalProgress] [] ``` ### Specific ``` Restart-D365Environment [[-ComputerName] ] [-Aos] [-Batch] [-FinancialReporter] [-DMF] [-Kill] [-ShowOriginalProgress] [] ``` ## DESCRIPTION Restart the different services in a Dynamics 365 Finance & Operations environment ## EXAMPLES ### EXAMPLE 1 ``` Restart-D365Environment -All ``` This will stop all services and then start all services again. ### EXAMPLE 2 ``` Restart-D365Environment -All -ShowOriginalProgress ``` This will stop all services and then start all services again. The progress of Stopping the different services will be written to the console / host. The progress of Starting the different services will be written to the console / host. ### EXAMPLE 3 ``` Restart-D365Environment -ComputerName "TEST-SB-AOS1","TEST-SB-AOS2","TEST-SB-BI1" -All ``` This will work against the machines: "TEST-SB-AOS1","TEST-SB-AOS2","TEST-SB-BI1". This will stop all services and then start all services again. ### EXAMPLE 4 ``` Restart-D365Environment -Aos -Batch ``` This will stop the AOS and Batch services and then start the AOS and Batch services again. ### EXAMPLE 5 ``` Restart-D365Environment -FinancialReporter -DMF ``` This will stop the FinancialReporter and DMF services and then start the FinancialReporter and DMF services again. ### EXAMPLE 6 ``` Restart-D365Environment -All -Kill ``` This will stop all services and then start all services again. It will use the Kill parameter to make sure that the services is stopped. ## PARAMETERS ### -ComputerName An array of computers that you want to work against ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: @($env:computername) Accept pipeline input: False Accept wildcard characters: False ``` ### -All Instructs the cmdlet work against all relevant services Includes: Aos Batch Financial Reporter DMF ```yaml Type: SwitchParameter Parameter Sets: Default Aliases: Required: False Position: 3 Default value: True Accept pipeline input: False Accept wildcard characters: False ``` ### -Aos Instructs the cmdlet to work against the AOS (IIS) service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 3 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Batch Instructs the cmdlet to work against the Batch service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 4 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -FinancialReporter Instructs the cmdlet to work against the Financial Reporter (Management Reporter 2012) ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 5 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -DMF Instructs the cmdlet to work against the DMF service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 6 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Kill Instructs the cmdlet to kill the service(s) that you want to restart ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Environment, Service, Services, Aos, Batch, Servicing Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Restore-D365DevConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Restore-D365DevConfig ## SYNOPSIS Restore the DynamicsDevConfig.xml file ## SYNTAX ``` Restore-D365DevConfig [[-Path] ] [-Force] [] ``` ## DESCRIPTION Will restore the DynamicsDevConfig.xml file located in the PackagesLocalDirectory\Bin folder ## EXAMPLES ### EXAMPLE 1 ``` Restore-D365DevConfig -Force ``` Will restore the DynamicsDevConfig.xml file, and overwrite the current DynamicsDevConfig.xml file in the PackagesLocalDirectory\Bin folder. It will use the default path "C:\Temp\d365fo.tools\DevConfigBackup" as the source directory. It will overwrite the current DynamicsDevConfig.xml file. A result set example: Filename LastModified File -------- ------------ ---- DynamicsDevConfig.xml 6/29/2021 7:31:04 PM K:\AosService\PackagesLocalDirectory\Bin\DynamicsDevConfig.xml ## PARAMETERS ### -Path Path to the folder where you the desired DynamicsDevConfig.xml file that you want restored is located Default is: "C:\Temp\d365fo.tools\DevConfigBackup" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $(Join-Path $Script:DefaultTempPath "DevConfigBackup") Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Instructs the cmdlet to overwrite the destination file if it already exists ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Web Server, IIS, IIS Express, Development Author: Sander Holvoet (@smholvoet) ## RELATED LINKS ================================================ FILE: docs/Restore-D365WebConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Restore-D365WebConfig ## SYNOPSIS Restore the web.config file ## SYNTAX ``` Restore-D365WebConfig [[-Path] ] [-Force] [] ``` ## DESCRIPTION Will restore the web.config file located back into the AOS / IIS folder ## EXAMPLES ### EXAMPLE 1 ``` Restore-D365WebConfig -Force ``` Will restore the web.config file, and overwrite the current web.config file in the AOS / IIS folder. It will use the default path "C:\Temp\d365fo.tools\WebConfigBackup" as the source directory. It will overwrite the current web.config file. A result set example: Filename LastModified File -------- ------------ ---- web.config 6/29/2021 7:31:04 PM K:\AosService\WebRoot\web.config ## PARAMETERS ### -Path Path to the folder where you the desired web.config file that you want restored is located Default is: "C:\Temp\d365fo.tools\WebConfigBackup" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $(Join-Path $Script:DefaultTempPath "WebConfigBackup") Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Instructs the cmdlet to overwrite the destination file if it already exists ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Send-D365BroadcastMessage.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Send-D365BroadcastMessage ## SYNOPSIS Send broadcast message to online users in D365FO ## SYNTAX ``` Send-D365BroadcastMessage [[-Tenant] ] [[-URL] ] [[-ClientId] ] [[-ClientSecret] ] [[-TimeZone] ] [[-StartTime] ] [[-EndingInMinutes] ] [-OnPremise] [] ``` ## DESCRIPTION Utilize the same messaging framework available from LCS and send a broadcast message to all online users in the environment ## EXAMPLES ### EXAMPLE 1 ``` Send-D365BroadcastMessage ``` This will send a message to all active users that are working on default D365FO environment. See the RELATED LINKS section for the supporting cmdlets needed to store a default configuration. ### EXAMPLE 2 ``` 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" ``` This will send a message to all active users that are working on the D365FO environment located at "https://usnconeboxax1aos.cloud.onebox.dynamics.com". It will authenticate against the Azure Active Directory with the "e674da86-7ee5-40a7-b777-1111111111111" guid. It will use the ClientId "dea8d7a9-1602-4429-b138-111111111111" and ClientSecret "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522" go get access to the environment. It will use the default value "UTC" Time Zone for converting the different time and dates. It will use the default start time which is NOW. It will use the default end time which is 60 minutes. ### EXAMPLE 3 ``` Send-D365BroadcastMessage -OnPremise -Tenant "https://adfs.local/adfs" -URL "https://ax-sandbox.d365fo.local" -ClientId "dea8d7a9-1602-4429-b138-111111111111" -ClientSecret "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522" ``` This will send a message to all active users that are working on the D365FO OnPremise environment located at "https://ax-sandbox.d365fo.local". It will authenticate against Local ADFS with the "https://adfs.local/adfs" path It will use the ClientId "dea8d7a9-1602-4429-b138-111111111111" and ClientSecret "Vja/VmdxaLOPR+alkjfsadffelkjlfw234522" go get access to the environment. It will use the default value "UTC" Time Zone for converting the different time and dates. It will use the default start time which is NOW. It will use the default end time which is 60 minutes. ## PARAMETERS ### -Tenant Azure Active Directory (AAD) tenant id (Guid) that the D365FO environment is connected to, that you want to send a message to ```yaml Type: String Parameter Sets: (All) Aliases: $AADGuid Required: False Position: 2 Default value: $Script:BroadcastTenant Accept pipeline input: False Accept wildcard characters: False ``` ### -URL URL / URI for the D365FO environment you want to send a message to ```yaml Type: String Parameter Sets: (All) Aliases: URI Required: False Position: 3 Default value: $Script:BroadcastUrl Accept pipeline input: False Accept wildcard characters: False ``` ### -ClientId The ClientId obtained from the Azure Portal when you created a Registered Application ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:BroadcastClientId Accept pipeline input: False Accept wildcard characters: False ``` ### -ClientSecret The ClientSecret obtained from the Azure Portal when you created a Registered Application ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:BroadcastClientSecret Accept pipeline input: False Accept wildcard characters: False ``` ### -TimeZone Id of the Time Zone your environment is running in You might experience that the local VM running the D365FO is running another Time Zone than the computer you are running this cmdlet from All available .NET Time Zones can be traversed with tab for this parameter The default value is "UTC" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:BroadcastTimeZone Accept pipeline input: False Accept wildcard characters: False ``` ### -StartTime The time and date you want the message to be displayed for the users Default value is NOW 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. ```yaml Type: DateTime Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: (Get-Date) Accept pipeline input: False Accept wildcard characters: False ``` ### -EndingInMinutes Specify how many minutes into the future you want this message / maintenance window to last Default value is 60 minutes 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. ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 8 Default value: $Script:BroadcastEndingInMinutes Accept pipeline input: False Accept wildcard characters: False ``` ### -OnPremise Specify if environnement is an D365 OnPremise Default value is "Not set" (= Cloud Environnement) ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: 9 Default value: $Script:BroadcastOnPremise Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES 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. For OnPremise environnement use -OnPremise flag to added "namespaces/AXSF" path to D365 URL and allow to get token from local ADFS server Tags: Servicing, Message, Users, Environment Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Add-D365BroadcastMessageConfig]() [Clear-D365ActiveBroadcastMessageConfig]() [Get-D365ActiveBroadcastMessageConfig]() [Get-D365BroadcastMessageConfig]() [Remove-D365BroadcastMessageConfig]() [Set-D365ActiveBroadcastMessageConfig]() ================================================ FILE: docs/Set-D365ActiveAzureStorageConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365ActiveAzureStorageConfig ## SYNOPSIS Set the active Azure Storage Account configuration ## SYNTAX ``` Set-D365ActiveAzureStorageConfig [[-Name] ] [[-ConfigStorageLocation] ] [-Temporary] [] ``` ## DESCRIPTION Updates the current active Azure Storage Account configuration with a new one ## EXAMPLES ### EXAMPLE 1 ``` Set-D365ActiveAzureStorageConfig -Name "UAT-Exports" ``` This will import the "UAT-Exports" set from the Azure Storage Account configurations. It will update the active Azure Storage Account configuration. ### EXAMPLE 2 ``` Set-D365ActiveAzureStorageConfig -Name "UAT-Exports" -ConfigStorageLocation "System" ``` This will import the "UAT-Exports" set from the Azure Storage Account configurations. It will update the active Azure Storage Account configuration. The data will be stored in the system wide configuration storage, which makes it accessible from all users. ### EXAMPLE 3 ``` Set-D365ActiveAzureStorageConfig -Name "UAT-Exports" -Temporary ``` This will import the "UAT-Exports" set from the Azure Storage Account configurations. It will update the active Azure Storage Account configuration. The update will only last for the rest of this PowerShell console session. ## PARAMETERS ### -Name The name the Azure Storage Account configuration you want to load into the active Azure Storage Account configuration ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ConfigStorageLocation Parameter used to instruct where to store the configuration objects The default value is "User" and this will store all configuration for the active user Valid options are: "User" "System" "System" will store the configuration so all users can access the configuration objects ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: User Accept pipeline input: False Accept wildcard characters: False ``` ### -Temporary Instruct the cmdlet to only temporarily override the persisted settings in the configuration storage ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) You will have to run the Initialize-D365Config cmdlet first, before this will be capable of working. You will have to run the Add-D365AzureStorageConfig cmdlet at least once, before this will be capable of working. ## RELATED LINKS ================================================ FILE: docs/Set-D365ActiveBroadcastMessageConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365ActiveBroadcastMessageConfig ## SYNOPSIS Set the active broadcast message configuration ## SYNTAX ``` Set-D365ActiveBroadcastMessageConfig [-Name] [-Temporary] [] ``` ## DESCRIPTION Updates the current active broadcast message configuration with a new one ## EXAMPLES ### EXAMPLE 1 ``` Set-D365ActiveBroadcastMessageConfig -Name "UAT" ``` This will set the broadcast message configuration named "UAT" as the active configuration. ## PARAMETERS ### -Name Name of the broadcast message configuration you want to load into the active broadcast message configuration ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Temporary Instruct the cmdlet to only temporarily override the persisted settings in the configuration store ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Servicing, Message, Users, Environment, Config, Configuration, ClientId, ClientSecret, OnPremise Author: Mötz Jensen (@Splaxi) ## RELATED LINKS [Add-D365BroadcastMessageConfig]() [Clear-D365ActiveBroadcastMessageConfig]() [Get-D365ActiveBroadcastMessageConfig]() [Get-D365BroadcastMessageConfig]() [Remove-D365BroadcastMessageConfig]() [Send-D365BroadcastMessage]() ================================================ FILE: docs/Set-D365Admin.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365Admin ## SYNOPSIS Powershell implementation of the AdminProvisioning tool ## SYNTAX ``` Set-D365Admin [-AdminSignInName] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [-EnableException] [] ``` ## DESCRIPTION Cmdlet using the AdminProvisioning tool from D365FO ## EXAMPLES ### EXAMPLE 1 ``` Set-D365Admin "claire@contoso.com" ``` This will provision claire@contoso.com as administrator for the environment ## PARAMETERS ### -AdminSignInName Email for the Admin ```yaml Type: String Parameter Sets: (All) Aliases: Email Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN) If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) Author: Mark Furrer (@devax_mf) ## RELATED LINKS ================================================ FILE: docs/Set-D365AzCopyPath.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365AzCopyPath ## SYNOPSIS Set the path for AzCopy.exe ## SYNTAX ``` Set-D365AzCopyPath [-Path] [] ``` ## DESCRIPTION Update the path where the module will be looking for the AzCopy.exe executable ## EXAMPLES ### EXAMPLE 1 ``` Invoke-D365InstallAzCopy -Path "C:\temp\d365fo.tools\AzCopy\AzCopy.exe" ``` This will update the path for the AzCopy.exe in the modules configuration ## PARAMETERS ### -Path Path to the AzCopy.exe ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Set-D365ClickOnceTrustPrompt.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365ClickOnceTrustPrompt ## SYNOPSIS Set the ClickOnce needed configuration ## SYNTAX ``` Set-D365ClickOnceTrustPrompt [] ``` ## DESCRIPTION Creates the needed registry keys and values for ClickOnce to work on the machine ## EXAMPLES ### EXAMPLE 1 ``` Set-D365ClickOnceTrustPrompt ``` This will create / or update the current ClickOnce configuration. ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Set-D365DefaultModelForNewProjects.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365DefaultModelForNewProjects ## SYNOPSIS Set the default model used creating new projects in Visual Studio ## SYNTAX ``` Set-D365DefaultModelForNewProjects [-Module] [] ``` ## 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 It will backup the current "DynamicsDevConfig.xml" file, for you to revert the changes if anything should go wrong ## EXAMPLES ### EXAMPLE 1 ``` Set-D365DefaultModelForNewProjects -Model "FleetManagement" ``` This will update the current default module registered in the "DynamicsDevConfig.xml" file. This file is located in Documents\Visual Studio Dynamics 365\ or in Documents\Visual Studio 2015\Settings\ depending on the version. It will backup the current "DynamicsDevConfig.xml" file. It will replace the value inside the "DefaultModelForNewProjects" tag. ## PARAMETERS ### -Module 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 ```yaml Type: String Parameter Sets: (All) Aliases: Model Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tag: Model, Models, Development, Default Model, Module, Project Author: Mötz Jensen (@Splaxi) The work for this cmdlet / function was inspired by Robin Kretzschmar (@DarkSmile92) blog post about changing the default model. The direct link for his blog post is: https://robscode.onl/d365-set-default-model-for-new-projects/ His main blog can found here: https://robscode.onl/ ## RELATED LINKS ================================================ FILE: docs/Set-D365FavoriteBookmark.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365FavoriteBookmark ## SYNOPSIS Enable the favorite bar and add an URL ## SYNTAX ### D365FO (Default) ``` Set-D365FavoriteBookmark [-URL ] [-D365FO] [] ``` ### AzureDevOps ``` Set-D365FavoriteBookmark [-URL ] [-AzureDevOps] [] ``` ## DESCRIPTION Enable the favorite bar in Edge & Chrome and put in the URL as a favorite/bookmark ## EXAMPLES ### EXAMPLE 1 ``` Set-D365FavoriteBookmark -Url "https://usnconeboxax1aos.cloud.onebox.dynamics.com" ``` This will add the "https://usnconeboxax1aos.cloud.onebox.dynamics.com" to the favorite bar, enable the favorite bar and lock it. This will be interpreted as the using the -D365FO parameter also, because that is the expected behavior. ### EXAMPLE 2 ``` Set-D365FavoriteBookmark -Url "https://usnconeboxax1aos.cloud.onebox.dynamics.com" -D365FO ``` This will add the "https://usnconeboxax1aos.cloud.onebox.dynamics.com" to the favorite bar, enable the favorite bar and lock it. The bookmark will be mapped as the one for the Dynamics 365 Finance & Operations instance. ### EXAMPLE 3 ``` Set-D365FavoriteBookmark -Url "https://CUSTOMERNAME.visualstudio.com/" -AzureDevOps ``` This will add the "https://CUSTOMERNAME.visualstudio.com/" to the favorite bar, enable the favorite bar and lock it. The bookmark will be mapped as the one for the Azure DevOps instance. ### EXAMPLE 4 ``` Get-D365Url | Set-D365FavoriteBookmark ``` This will get the URL from the environment and add that to the favorite bar, enable the favorite bar and lock it. This will be interpreted as the using the -D365FO parameter also, because that is the expected behavior. ## PARAMETERS ### -URL The URL of the shortcut you want to add to the favorite bar ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -D365FO Instruct the cmdlet that you want the populate the D365FO favorite entry based on the URL provided ```yaml Type: SwitchParameter Parameter Sets: D365FO Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -AzureDevOps Instruct the cmdlet that you want the populate the AzureDevOps favorite entry based on the URL provided ```yaml Type: SwitchParameter Parameter Sets: AzureDevOps Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Set-D365FlightServiceCatalogId.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365FlightServiceCatalogId ## SYNOPSIS Set the FlightingServiceCatalogID ## SYNTAX ``` Set-D365FlightServiceCatalogId [[-FlightServiceCatalogId] ] [[-AosServiceWebRootPath] ] [] ``` ## DESCRIPTION Set the FlightingServiceCatalogID element in the web.config file used by D365FO ## EXAMPLES ### EXAMPLE 1 ``` Set-D365FlightServiceCatalogId ``` This will set the FlightingServiceCatalogID element the web.config to the default value "12719367". ## PARAMETERS ### -FlightServiceCatalogId Flighting catalog ID to be set ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: 12719367 Accept pipeline input: False Accept wildcard characters: False ``` ### -AosServiceWebRootPath Path to the root folder where to locate the web.config file ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:AOSPath Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Flight, Flighting Author: Frank Hüther(@FrankHuether)) The DataAccess.FlightingServiceCatalogID element must already exist in the web.config file, which is expected to be the case in newer environments. 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 ## RELATED LINKS ================================================ FILE: docs/Set-D365LcsApiConfig.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365LcsApiConfig ## SYNOPSIS Set the LCS configuration details ## SYNTAX ``` Set-D365LcsApiConfig [[-ProjectId] ] [[-ClientId] ] [[-BearerToken] ] [[-ActiveTokenExpiresOn] ] [[-RefreshToken] ] [[-LcsApiUri] ] [-Temporary] [] ``` ## DESCRIPTION Set the LCS configuration details and save them into the configuration store ## EXAMPLES ### EXAMPLE 1 ``` Set-D365LcsApiConfig -ProjectId 123456789 -ClientId "9b4f4503-b970-4ade-abc6-2c086e4c4929" -BearerToken "JldjfafLJdfjlfsalfd..." -ActiveTokenExpiresOn 1556909205 -RefreshToken "Tsdljfasfe2j32324" -LcsApiUri "https://lcsapi.lcs.dynamics.com" ``` This will set the LCS API configuration. The ProjectId 123456789 will be saved as the default ProjectId for all cmdlets that will interact with LCS, if they require a ProjectId. 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. 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. The ActiveTokenExpiresOn 1556909205 will be saved to assist the module in determine whether the BearerToken is still valid or not. The RefreshToken "Tsdljfasfe2j32324" will be saved as the default RefreshToken for all cmdlets that will interact with tokens. The LcsApiUri "https://lcsapi.lcs.dynamics.com" will be saved as the default LCS HTTP endpoint for all cmdlets that will interact with LCS. ### EXAMPLE 2 ``` Get-D365LcsApiToken -Username "serviceaccount@domain.com" -Password "TopSecretPassword" | Set-D365LcsApiConfig ``` This will obtain a valid OAuth 2.0 access token from Azure Active Directory and save the needed details. 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". The output object received from Get-D365LcsApiToken is piped directly to Set-D365LcsApiConfig. Set-D365LcsApiConfig will save the access_token(BearerToken), refresh_token(RefreshToken) and expires_on(ActiveTokenExpiresOn). These values will then be available as default values for all LCS cmdlets across the module. You can validate the current default values by calling Get-D365LcsApiConfig. ## PARAMETERS ### -ProjectId The project id for the Dynamics 365 for Finance & Operations project inside LCS ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: 0 Accept pipeline input: False Accept wildcard characters: False ``` ### -ClientId The Azure Registered Application Id / Client Id obtained while creating a Registered App inside the Azure Portal ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -BearerToken The token you want to use when working against the LCS api ```yaml Type: String Parameter Sets: (All) Aliases: AccessToken, access_token Required: False Position: 3 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -ActiveTokenExpiresOn The point in time where the current bearer token will expire The time is measured in Unix Time, total seconds since 1970-01-01 ```yaml Type: Int64 Parameter Sets: (All) Aliases: expires_on Required: False Position: 4 Default value: 0 Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -RefreshToken The Refresh Token that you want to use for the authentication process ```yaml Type: String Parameter Sets: (All) Aliases: refresh_token Required: False Position: 5 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -LcsApiUri URI / URL to the LCS API you want to use The value depends on where your LCS project is located. There are multiple valid URI's / URL's Valid options: "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" ```yaml Type: String Parameter Sets: (All) Aliases: resource Required: False Position: 6 Default value: Https://lcsapi.lcs.dynamics.com Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Temporary Instruct the cmdlet to only temporarily override the persisted settings in the configuration storage ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Environment, Url, Config, Configuration, LCS, Upload, ClientId Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Set-D365NugetPath.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365NugetPath ## SYNOPSIS Set the path for nuget.exe ## SYNTAX ``` Set-D365NugetPath [-Path] [] ``` ## DESCRIPTION Update the path where the module will be looking for the nuget.exe executable ## EXAMPLES ### EXAMPLE 1 ``` Set-D365NugetPath -Path "C:\temp\d365fo.tools\nuget\nuget.exe" ``` This will update the path for the nuget.exe in the modules configuration ## PARAMETERS ### -Path Path to the nuget.exe ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Set-D365OfflineAuthenticationAdminEmail.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365OfflineAuthenticationAdminEmail ## SYNOPSIS Sets the offline administrator e-mail ## SYNTAX ``` Set-D365OfflineAuthenticationAdminEmail [-Email] [] ``` ## DESCRIPTION Sets the registered offline administrator in the "DynamicsDevConfig.xml" file located in the default Package Directory ## EXAMPLES ### EXAMPLE 1 ``` Set-D365OfflineAuthenticationAdminEmail -Email "admin@contoso.com" ``` Will update the Offline Administrator E-mail address in the DynamicsDevConfig.xml file with "admin@contoso.com" ## PARAMETERS ### -Email The desired email address of the to be offline administrator ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES This cmdlet is inspired by the work of "Sheikh Sohail Hussain" (twitter: @SSohailHussain) His blog can be found here: http://d365technext.blogspot.com The specific blog post that we based this cmdlet on can be found here: http://d365technext.blogspot.com/2018/07/offline-authentication-admin-email.html Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Set-D365RsatConfiguration.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365RsatConfiguration ## SYNOPSIS Set different RSAT configuration values ## SYNTAX ``` Set-D365RsatConfiguration [[-LogGenerationEnabled] ] [[-VerboseSnapshotsEnabled] ] [[-AddOperatorFieldsToExcelValidationEnabled] ] [[-RSATConfigFilename] ] [] ``` ## DESCRIPTION Update different RSAT configuration values while using the tool ## EXAMPLES ### EXAMPLE 1 ``` Set-D365RsatConfiguration -LogGenerationEnabled $true ``` This will enable the log generation logic of RSAT. ### EXAMPLE 2 ``` Set-D365RsatConfiguration -VerboseSnapshotsEnabled $true ``` This will enable the snapshot generation logic of RSAT. ### EXAMPLE 3 ``` Set-D365RsatConfiguration -AddOperatorFieldsToExcelValidationEnabled $true ``` This will enable the operator generation logic of RSAT. ## PARAMETERS ### -LogGenerationEnabled Will set the LogGeneration property $true will make RSAT start generating logs $false will stop RSAT from generating logs ```yaml Type: Boolean Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -VerboseSnapshotsEnabled Will set the VerboseSnapshotsEnabled property $true will make RSAT start generating snapshots and store related details $false will stop RSAT from generating snapshots and store related details ```yaml Type: Boolean Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -AddOperatorFieldsToExcelValidationEnabled Will set the AddOperatorFieldsToExcelValidation property $true will make RSAT start adding the operation options in the excel parameter file $false will stop RSAT from adding the operation options in the excel parameter file ```yaml Type: Boolean Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -RSATConfigFilename Specifies the file name of the RSAT configuration file. Default is 'Microsoft.Dynamics.RegressionSuite.WpfApp.exe.config' If you are using an older version of RSAT, you might need to change this to 'Microsoft.Dynamics.RegressionSuite.WindowsApp.exe.config' ```yaml Type: Object Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: Microsoft.Dynamics.RegressionSuite.WpfApp.exe.config Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, Configuration Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Set-D365RsatTier2Crypto.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365RsatTier2Crypto ## SYNOPSIS Set the needed configuration to work on Tier2+ environments ## SYNTAX ``` Set-D365RsatTier2Crypto [] ``` ## DESCRIPTION Set the needed registry settings for when you are running RSAT against a Tier2+ environment ## EXAMPLES ### EXAMPLE 1 ``` Set-D365RsatTier2Crypto ``` This will configure the registry to support RSAT against a Tier2+ environment. ## PARAMETERS ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: RSAT, Testing, Regression Suite Automation Test, Regression, Test, Automation, Configuration Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Set-D365SDPCleanUp.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365SDPCleanUp ## SYNOPSIS Set the cleanup retention period ## SYNTAX ``` Set-D365SDPCleanUp [[-NumberOfDays] ] [] ``` ## DESCRIPTION Sets the configured retention period before updates are deleted ## EXAMPLES ### EXAMPLE 1 ``` Set-D365SDPCleanUp -NumberOfDays 10 ``` This will set the retention period to 10 days inside the the registry The cmdlet REQUIRES elevated permissions to run, otherwise it will fail ## PARAMETERS ### -NumberOfDays Number of days that deployable software packages should remain on the server ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: 30 Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES This cmdlet is based on the findings from Alex Kwitny (@AlexOnDAX) See his blog for more info: http://www.alexondax.com/2018/04/msdyn365fo-how-to-adjust-your.html Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Set-D365SqlPackagePath.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365SqlPackagePath ## SYNOPSIS Set the path for SqlPackage.exe ## SYNTAX ``` Set-D365SqlPackagePath [-Path] [] ``` ## DESCRIPTION Update the path where the module will be looking for the SqlPackage.exe executable ## EXAMPLES ### EXAMPLE 1 ``` Set-D365SqlPackagePath -Path "C:\Program Files\Microsoft SQL Server\150\DAC\bin\SqlPackage.exe" ``` This will update the path for the SqlPackage.exe in the modules configuration ## PARAMETERS ### -Path Path to the SqlPackage.exe ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Set-D365StartPage.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365StartPage ## SYNOPSIS Sets the start page in internet explorer ## SYNTAX ### Default (Default) ``` Set-D365StartPage [-Name] [] ``` ### Url ``` Set-D365StartPage [-Url] [] ``` ## DESCRIPTION Function for setting the start page in internet explorer ## EXAMPLES ### EXAMPLE 1 ``` Set-D365StartPage -Name 'Demo1' ``` This will update the start page for the current user to "https://Demo1.cloud.onebox.dynamics.com" ### EXAMPLE 2 ``` Set-D365StartPage -URL "https://uat.sandbox.operations.dynamics.com" ``` This will update the start page for the current user to "https://uat.sandbox.operations.dynamics.com" ## PARAMETERS ### -Name Name of the D365 Instance ```yaml Type: String Parameter Sets: Default Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Url URL of the D365 for Finance & Operations instance that you want to have as your start page ```yaml Type: String Parameter Sets: Url Aliases: Required: True Position: 2 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Set-D365SysAdmin.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365SysAdmin ## SYNOPSIS Set a user to sysadmin ## SYNTAX ``` Set-D365SysAdmin [[-User] ] [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [] ``` ## DESCRIPTION Set a user to sysadmin inside the SQL Server ## EXAMPLES ### EXAMPLE 1 ``` Set-D365SysAdmin ``` This will configure the local administrator on the machine as a SYSADMIN inside SQL Server For this to run you need to be running it from a elevated console ### EXAMPLE 2 ``` Set-D365SysAdmin -SqlPwd Test123 ``` This will configure the local administrator on the machine as a SYSADMIN inside SQL Server. It will logon as the default SqlUser but use the provided SqlPwd. This can be run from a non-elevated console ## PARAMETERS ### -User The user that you want to make sysadmin Most be well formatted server\user or domain\user. Default value is: machinename\administrator ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: "$env:computername\administrator" Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@splaxi) ## RELATED LINKS ================================================ FILE: docs/Set-D365TraceParserFileSize.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365TraceParserFileSize ## SYNOPSIS Configue a new maximum file size for the TraceParser ## SYNTAX ``` Set-D365TraceParserFileSize [-FileSizeInMB] [[-Path] ] [] ``` ## DESCRIPTION Change the maximum file size that the TraceParser generates ## EXAMPLES ### EXAMPLE 1 ``` Set-D365TraceParserFileSize -FileSizeInMB 2048 ``` This will configure the maximum TraceParser file to 2048 MB. ## PARAMETERS ### -FileSizeInMB The maximum size that you want to allow the TraceParser file to grow to Original value inside the configuration is 1024 (MB) ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Path The path to the TraceParser.config file that you want to edit The default path is: "\AosService\Webroot\Services\TraceParserService\TraceParserService.config" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: (Join-Path $Script:AOSPath "Services\TraceParserService\TraceParserService.config") Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Set-D365WebConfigDatabase.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365WebConfigDatabase ## SYNOPSIS Set the database connection details ## SYNTAX ``` Set-D365WebConfigDatabase [-DatabaseServer] [-DatabaseName] [-SqlUser] [-SqlPwd] [[-Path] ] [] ``` ## DESCRIPTION Overwrite the current database connection details directly in the web.config file 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 ## EXAMPLES ### EXAMPLE 1 ``` Set-D365WebConfigDatabase -DatabaseServer TestServer.database.windows.net -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" ``` Will overwrite Server, Database, Username and Password directly in the web.config file. It will save all details unencrypted. ## PARAMETERS ### -DatabaseServer The name of the database server Obtain when you request JIT (Just-in-Time) access through the LCS portal ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database Obtain when you request JIT (Just-in-Time) access through the LCS portal ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance Obtain when you request JIT (Just-in-Time) access through the LCS portal ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user Obtain when you request JIT (Just-in-Time) access through the LCS portal ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 4 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Path Path to the web.config file that you want to update with new SQL connection details Default is: "K:\AosService\WebRoot\web.config" or what else drive that is recognized by the D365FO components as the service drive ```yaml Type: Object Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: $(Join-Path -Path $Script:AOSPath -ChildPath $Script:WebConfig) Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: DEV, Tier2, DB, Database, Debug, JIT, LCS, Azure DB Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Set-D365WebServerType.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365WebServerType ## SYNOPSIS Set the web server type to be used to run the D365FO instance ## SYNTAX ``` Set-D365WebServerType [-RuntimeHostType] [] ``` ## DESCRIPTION Set the web server which will be used to run D365FO: Either IIS or IIS Express. Newly deployed development machines will have this set to IIS Express by default. It will backup the current "DynamicsDevConfig.xml" file, for you to revert the changes if anything should go wrong. It will look for the file located in the default Package Directory. ## EXAMPLES ### EXAMPLE 1 ``` Set-D365WebServerType -RuntimeHostType "IIS" ``` This will update the current web server type registered in the "DynamicsDevConfig.xml" file. This file is located "K:\AosService\PackagesLocalDirectory\bin". It will backup the current "DynamicsDevConfig.xml" file. It will replace the value inside the "RuntimeHostType" tag. ## PARAMETERS ### -RuntimeHostType The type of web server you want to use. Valid options are: "IIS" "IISExpress" ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tag: Web Server, IIS, IIS Express, Development Author: Sander Holvoet (@smholvoet) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Set-D365WorkstationMode.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Set-D365WorkstationMode ## SYNOPSIS Set the Workstation mode ## SYNTAX ``` Set-D365WorkstationMode [-Enabled] [] ``` ## DESCRIPTION Set the Workstation mode to enabled or not It is used to enable the tool to run on a personal machine and still be able to call Invoke-D365TableBrowser and Invoke-D365SysRunnerClass ## EXAMPLES ### EXAMPLE 1 ``` Set-D365WorkstationMode -Enabled $true ``` This will enable the Workstation mode. You will have to restart the powershell session when you switch around. ## PARAMETERS ### -Enabled $True enables the workstation mode while $false deactivated the workstation mode ```yaml Type: Boolean Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) You will have to run the Initialize-D365Config cmdlet first, before this will be capable of working. ## RELATED LINKS ================================================ FILE: docs/Start-D365Environment.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Start-D365Environment ## SYNOPSIS Cmdlet to start the different services in a Dynamics 365 Finance & Operations environment ## SYNTAX ### Default (Default) ``` Start-D365Environment [[-ComputerName] ] [-All] [-OnlyStartTypeAutomatic] [-ShowOriginalProgress] [] ``` ### Specific ``` Start-D365Environment [[-ComputerName] ] [-Aos] [-Batch] [-FinancialReporter] [-DMF] [-OnlyStartTypeAutomatic] [-ShowOriginalProgress] [] ``` ## DESCRIPTION Can start all relevant services that is running in a D365FO environment ## EXAMPLES ### EXAMPLE 1 ``` Start-D365Environment ``` This will run the cmdlet with the default parameters. Default is "-All". This will start all D365FO services on the machine. ### EXAMPLE 2 ``` Start-D365Environment -OnlyStartTypeAutomatic ``` This will start all D365FO services on the machine that are configured for Automatic startup. It will exclude all services that are either manual or disabled in their startup configuration. ### EXAMPLE 3 ``` Start-D365Environment -ShowOriginalProgress ``` This will run the cmdlet with the default parameters. Default is "-All". This will start all D365FO services on the machine. The progress of starting the different services will be written to the console / host. ### EXAMPLE 4 ``` Start-D365Environment -All ``` This will start all D365FO services on the machine. ### EXAMPLE 5 ``` Start-D365Environment -Aos -Batch ``` This will start the Aos & Batch D365FO services on the machine. ### EXAMPLE 6 ``` Start-D365Environment -FinancialReporter -DMF ``` This will start the FinancialReporter and DMF services on the machine. ## PARAMETERS ### -ComputerName An array of computers that you want to start services on. ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: @($env:computername) Accept pipeline input: False Accept wildcard characters: False ``` ### -All Set when you want to start all relevant services Includes: Aos Batch Financial Reporter ```yaml Type: SwitchParameter Parameter Sets: Default Aliases: Required: False Position: 3 Default value: True Accept pipeline input: False Accept wildcard characters: False ``` ### -Aos Start the Aos (iis) service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 3 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Batch Start the batch service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 4 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -FinancialReporter Start the financial reporter (Management Reporter 2012) service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 5 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -DMF Start the Data Management Framework service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 6 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OnlyStartTypeAutomatic Instruct the cmdlet to filter out services that are set to manual start or disabled ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Start-D365EnvironmentV2.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Start-D365EnvironmentV2 ## SYNOPSIS Cmdlet to start the different services in a Dynamics 365 Finance & Operations environment ## SYNTAX ### Default (Default) ``` Start-D365EnvironmentV2 [-All] [-OnlyStartTypeAutomatic] [-ShowOriginalProgress] [] ``` ### Specific ``` Start-D365EnvironmentV2 [-Aos] [-Batch] [-FinancialReporter] [-DMF] [-OnlyStartTypeAutomatic] [-ShowOriginalProgress] [] ``` ## DESCRIPTION Can start all relevant services that is running in a D365FO environment ## EXAMPLES ### EXAMPLE 1 ``` Start-D365EnvironmentV2 ``` This will run the cmdlet with the default parameters. Default is "-All". This will start all D365FO services on the machine. ### EXAMPLE 2 ``` Start-D365EnvironmentV2 -OnlyStartTypeAutomatic ``` This will start all D365FO services on the machine that are configured for Automatic startup. It will exclude all services that are either manual or disabled in their startup configuration. ### EXAMPLE 3 ``` Start-D365EnvironmentV2 -ShowOriginalProgress ``` This will run the cmdlet with the default parameters. Default is "-All". This will start all D365FO services on the machine. The progress of starting the different services will be written to the console / host. ### EXAMPLE 4 ``` Start-D365EnvironmentV2 -All ``` This will start all D365FO services on the machine. ### EXAMPLE 5 ``` Start-D365EnvironmentV2 -Aos -Batch ``` This will start the Aos & Batch D365FO services on the machine. ### EXAMPLE 6 ``` Start-D365EnvironmentV2 -FinancialReporter -DMF ``` This will start the FinancialReporter and DMF services on the machine. ### EXAMPLE 7 ``` Enable-D365Exception ``` PS C:\\\> Start-D365EnvironmentV2 This will run the cmdlet with the default parameters. Default is "-All". This will start all D365FO services on the machine. If a service does not start, it will throw an exception. ## PARAMETERS ### -All Set when you want to start all relevant services Includes: Aos Batch Financial Reporter Data Management Framework ```yaml Type: SwitchParameter Parameter Sets: Default Aliases: Required: False Position: 2 Default value: True Accept pipeline input: False Accept wildcard characters: False ``` ### -Aos Start the Aos (iis) service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 2 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Batch Start the batch service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 3 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -FinancialReporter Start the financial reporter (Management Reporter 2012) service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 4 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -DMF Start the Data Management Framework service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 5 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -OnlyStartTypeAutomatic Instruct the cmdlet to filter out services that are set to manual start or disabled ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Vincent Verweij (@VincentVerweij) ## RELATED LINKS ================================================ FILE: docs/Start-D365EventTrace.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Start-D365EventTrace ## SYNOPSIS Start an Event Trace session ## SYNTAX ``` Start-D365EventTrace [-ProviderName] [[-OutputPath] ] [[-SessionName] ] [[-FileName] ] [[-OutputFormat] ] [[-MinBuffer] ] [[-MaxBuffer] ] [[-BufferSizeKB] ] [[-MaxLogFileSizeMB] ] [] ``` ## DESCRIPTION Start an Event Trace session with default values to help you getting started ## EXAMPLES ### EXAMPLE 1 ``` Start-D365EventTrace -ProviderName "Microsoft-Dynamics-AX-FormServer","Microsoft-Dynamics-AX-XppRuntime" ``` This will start a new Event Tracing session with the binary circular output format. It uses "Microsoft-Dynamics-AX-FormServer","Microsoft-Dynamics-AX-XppRuntime" as the providernames. It uses the default output folder "C:\Temp\d365fo.tools\EventTrace". It will use the default values for the remaining parameters. ### EXAMPLE 2 ``` Start-D365EventTrace -ProviderName "Microsoft-Dynamics-AX-FormServer","Microsoft-Dynamics-AX-XppRuntime" -OutputFormat CSV ``` This will start a new Event Tracing session with the comma separated output format. It uses "Microsoft-Dynamics-AX-FormServer","Microsoft-Dynamics-AX-XppRuntime" as the providernames. It uses the default output folder "C:\Temp\d365fo.tools\EventTrace". It will use the default values for the remaining parameters. ## PARAMETERS ### -ProviderName Name of the provider(s) you want to have part of your trace Accepts an array/list of provider names ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -OutputPath Path to the output folder where you want to store the ETL file that will be generated Default path is "C:\Temp\d365fo.tools\EventTrace" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: (Join-Path -Path $Script:DefaultTempPath -ChildPath "EventTrace") Accept pipeline input: False Accept wildcard characters: False ``` ### -SessionName Name that you want the tracing session to have while running the trace Default value is "d365fo.tools.trace" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: D365fo.tools.trace Accept pipeline input: False Accept wildcard characters: False ``` ### -FileName Name of the file that you want the trace to write its output to Default value is "d365fo.tools.trace.etl" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: D365fo.tools.trace.etl Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputFormat The desired output format of the ETL file being outputted from the tracing session Default value is "bincirc" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 5 Default value: Bincirc Accept pipeline input: False Accept wildcard characters: False ``` ### -MinBuffer The minimum buffer size in MB that you want the tracing session to work with Default value is 10240 ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: 10240 Accept pipeline input: False Accept wildcard characters: False ``` ### -MaxBuffer The maximum buffer size in MB that you want the tracing session to work with Default value is 10240 ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: 10240 Accept pipeline input: False Accept wildcard characters: False ``` ### -BufferSizeKB The buffer size in KB that you want the tracing session to work with Default value is 1024 ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 8 Default value: 1024 Accept pipeline input: False Accept wildcard characters: False ``` ### -MaxLogFileSizeMB The maximum log file size in MB that you want the tracing session to work with Default value is 4096 ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: 9 Default value: 4096 Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: ETL, EventTracing, EventTrace Author: Mötz Jensen (@Splaxi) This cmdlet/function was inspired by the work of Michael Stashwick (@D365Stuff) He blog is located here: https://www.d365stuff.co/ 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/ ## RELATED LINKS ================================================ FILE: docs/Stop-D365Environment.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Stop-D365Environment ## SYNOPSIS Cmdlet to stop the different services in a Dynamics 365 Finance & Operations environment ## SYNTAX ### Default (Default) ``` Stop-D365Environment [[-ComputerName] ] [-All] [-Kill] [-ShowOriginalProgress] [] ``` ### Specific ``` Stop-D365Environment [[-ComputerName] ] [-Aos] [-Batch] [-FinancialReporter] [-DMF] [-Kill] [-ShowOriginalProgress] [] ``` ## DESCRIPTION Can stop all relevant services that is running in a D365FO environment ## EXAMPLES ### EXAMPLE 1 ``` Stop-D365Environment ``` This will run the cmdlet with the default parameters. Default is "-All". This will stop all D365FO services on the machine. ### EXAMPLE 2 ``` Stop-D365Environment -ShowOriginalProgress ``` This will run the cmdlet with the default parameters. Default is "-All". This will Stop all D365FO services on the machine. The progress of Stopping the different services will be written to the console / host. ### EXAMPLE 3 ``` Stop-D365Environment -All ``` This will stop all D365FO services on the machine. ### EXAMPLE 4 ``` Stop-D365Environment -Aos -Batch ``` This will stop the Aos & Batch D365FO services on the machine. ### EXAMPLE 5 ``` Stop-D365Environment -FinancialReporter -DMF ``` This will stop the FinancialReporter and DMF services on the machine. ### EXAMPLE 6 ``` Stop-D365Environment -All -Kill ``` This will stop all D365FO services on the machine. It will use the Kill parameter to make sure that the services is stopped. ## PARAMETERS ### -ComputerName An array of computers that you want to stop services on. ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: @($env:computername) Accept pipeline input: False Accept wildcard characters: False ``` ### -All Set when you want to stop all relevant services Includes: Aos Batch Financial Reporter ```yaml Type: SwitchParameter Parameter Sets: Default Aliases: Required: False Position: 3 Default value: True Accept pipeline input: False Accept wildcard characters: False ``` ### -Aos Stop the Aos (iis) service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 3 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Batch Stop the batch service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 4 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -FinancialReporter Start the financial reporter (Management Reporter 2012) service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 5 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -DMF Start the Data Management Framework service ```yaml Type: SwitchParameter Parameter Sets: Specific Aliases: Required: False Position: 6 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -Kill Instructs the cmdlet to kill the service(s) that you want to stop ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: 7 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowOriginalProgress Instruct the cmdlet to show the standard output in the console Default is $false which will silence the standard output ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: 8 Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Stop-D365EventTrace.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Stop-D365EventTrace ## SYNOPSIS Stop an Event Trace session ## SYNTAX ``` Stop-D365EventTrace [[-SessionName] ] [] ``` ## DESCRIPTION Stop an Event Trace session that you have started earlier with the d365fo.tools ## EXAMPLES ### EXAMPLE 1 ``` Stop-D365EventTrace ``` This will stop an Event Trace session. It will use the "d365fo.tools.trace" as the SessionName parameter. ## PARAMETERS ### -SessionName Name of the tracing session that you want to stop Default value is "d365fo.tools.trace" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: D365fo.tools.trace Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: ETL, EventTracing, EventTrace Author: Mötz Jensen (@Splaxi) This cmdlet/function was inspired by the work of Michael Stashwick (@D365Stuff) He blog is located here: https://www.d365stuff.co/ 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/ ## RELATED LINKS ================================================ FILE: docs/Switch-D365ActiveDatabase.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Switch-D365ActiveDatabase ## SYNOPSIS Switches the 2 databases. The Old wil be renamed _original ## SYNTAX ``` Switch-D365ActiveDatabase [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [-SourceDatabaseName] [[-DestinationSuffix] ] [-EnableException] [] ``` ## DESCRIPTION Switches the 2 databases. The Old wil be renamed _original ## EXAMPLES ### EXAMPLE 1 ``` Switch-D365ActiveDatabase -SourceDatabaseName "GoldenConfig" ``` This will switch the default database AXDB out and put "GoldenConfig" in its place instead. It will use the default value for DestinationSuffix which is "_original". The destination database "AXDB" will be renamed to "AXDB_original". The GoldenConfig database will be renamed to "AXDB". ### EXAMPLE 2 ``` Switch-D365ActiveDatabase -SourceDatabaseName "AXDB_original" -DestinationSuffix "_reverted" ``` This will switch the default database AXDB out and put "AXDB_original" in its place instead. It will use the "_reverted" value for DestinationSuffix parameter. The destination database "AXDB" will be renamed to "AXDB_reverted". The "AXDB_original" database will be renamed to "AXDB". This is used when you did a switch already and need to switch back to the original database. This example assumes that the used the first example to switch in the GoldenConfig database with default parameters. ## PARAMETERS ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: DestinationDatabaseName Required: False Position: 2 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -SourceDatabaseName The database that takes the DatabaseName's place ```yaml Type: String Parameter Sets: (All) Aliases: NewDatabaseName Required: True Position: 5 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -DestinationSuffix The suffix that you want to append onto the database that is being switched out (DestinationDatabaseName / DatabaseName) The default value is "_original" to mimic the official guides from Microsoft ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: _original Accept pipeline input: False Accept wildcard characters: False ``` ### -EnableException This parameters disables user-friendly warnings and enables the throwing of exceptions This is less user friendly, but allows catching exceptions in calling scripts ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) Author: Rasmus Andersen (@ITRasmus) ## RELATED LINKS ================================================ FILE: docs/Test-D365Command.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Test-D365Command ## SYNOPSIS Validate or show parameter set details with colored output ## SYNTAX ``` Test-D365Command [-CommandText] [-Mode] [-SplatInput ] [-ShowSplatStyleV1] [-ShowSplatStyleV2] [-IncludeHelp] [] ``` ## DESCRIPTION Analyze a function and it's parameters The cmdlet / function is capable of validating a string input with function name and parameters ## EXAMPLES ### EXAMPLE 1 ``` Test-D365Command -CommandText 'Import-D365Bacpac -ImportModeTier2 -SqlUser "sqladmin" -SqlPwd "XyzXyz" -BacpacFile2 "C:\temp\uat.bacpac"' -Mode "Validate" -IncludeHelp ``` This will validate all the parameters that have been passed to the Import-D365Bacpac cmdlet. All supplied parameters that matches a parameter will be marked with an asterisk. Will print the coloring help. ### EXAMPLE 2 ``` Test-D365Command -CommandText 'Import-D365Bacpac' -Mode "ShowParameters" -IncludeHelp ``` This will display all the parameter sets and their individual parameters. Will print the coloring help. ### EXAMPLE 3 ``` $params = @{} ``` PS C:\\\> $params.DatabaseName = "SAMPLEVALUE" PS C:\\\> Test-D365Command -CommandText 'Import-D365Bacpac -ImportModeTier2' -SplatInput $params -Mode "Validate" This builds a hashtable with a property names "DatabaseName". The hashtable is passed to the cmdlet to be part of the validation. ## PARAMETERS ### -CommandText The string that you want to analyze If there is parameter value present, you have to use the opposite quote strategy to encapsulate the string correctly E.g. for double quotes -CommandText 'Import-D365Bacpac -ImportModeTier2 -SqlUser "sqladmin" -SqlPwd "XyzXyz" -BacpacFile2 "C:\temp\uat.bacpac"' E.g. for single quotes -CommandText "Import-D365Bacpac -ExportModeTier2 -SqlUser 'sqladmin' -SqlPwd 'XyzXyz' -BacpacFile2 'C:\temp\uat.bacpac'" ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Mode The operation mode of the cmdlet / function Valid options are: - Validate - ShowParameters ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 3 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -SplatInput Pass in your hashtable that you use for your command execution and have it validated ```yaml Type: Hashtable Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowSplatStyleV1 Include an hashtable splatting for all parameter sets in the output The example is built like this: PS C:\\\> $params = @{} PS C:\\\> $params.PropertyName = "SAMPLEVALUE" PS C:\\\> Test-FakeCommand @params ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -ShowSplatStyleV2 Include an hashtable splatting for all parameter sets in the output The example is built like this: PS C:\\\> $params = @{ PS C:\\\> PropertyName = "SAMPLEVALUE" PS C:\\\> } PS C:\\\> Test-FakeCommand @params ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### -IncludeHelp Switch to instruct the cmdlet / function to output a simple guide with the colors in it ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Test-D365DataverseConnection.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Test-D365DataverseConnection ## SYNOPSIS Test the dataverse connection ## SYNTAX ``` Test-D365DataverseConnection [[-BinDir] ] [] ``` ## DESCRIPTION Invokes the built-in http communication endpount, that validates the connection between the D365FO environment and dataverse ## EXAMPLES ### EXAMPLE 1 ``` Test-D365DataverseConnection ``` This will invoke the http communication component, that validates the basic settings between D365FO and Dataverse. It will output the raw details from the call, to make it easier to troubleshoot the connectivity between D365FO and Dataverse. ## PARAMETERS ### -BinDir The path to the bin directory for the environment Default path is the same as the aos service PackagesLocalDirectory\bin ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: "$Script:BinDir\bin" Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES General notes ## RELATED LINKS ================================================ FILE: docs/Test-D365EntraIntegration.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Test-D365EntraIntegration ## SYNOPSIS Test the Entra Id integration ## SYNTAX ``` Test-D365EntraIntegration ``` ## DESCRIPTION Validates the configuration of the web.config file and the certificate for the environment If any of the configuration is missing or in someway incorrect, it will prompt and stating corrective actions needed ## EXAMPLES ### EXAMPLE 1 ``` Test-D365EntraIntegration ``` This will validate the settings inside the web.config file. It will search for Aad.Realm, Infrastructure.S2SCertThumbprint, GraphApi.GraphAPIServicePrincipalCert It will search for the certificate that matches the thumbprint. A result set example: EntraAppId Thumbprint Subject Expiration ---------- ---------- ------- ---------- e068e004-8bec-48c3-a36f-2ab4982ee738 0768175DF3DFDEA3FA78925ADC1E588707649335 CN=CHEAuth 2/5/2026 8:09:28 AM ## PARAMETERS ## INPUTS ## OUTPUTS ## NOTES Based on: https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-tools/secure-developer-vm#external-integrations Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Test-D365FlightServiceCatalogId.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Test-D365FlightServiceCatalogId ## SYNOPSIS Test if the FlightingServiceCatalogID is present and filled out ## SYNTAX ``` Test-D365FlightServiceCatalogId [[-AosServiceWebRootPath] ] [] ``` ## DESCRIPTION Test if the FlightingServiceCatalogID element exists in the web.config file used by D365FO ## EXAMPLES ### EXAMPLE 1 ``` Test-D365FlightServiceCatalogId ``` This will open the web.config and check if the FlightingServiceCatalogID element is present or not. ## PARAMETERS ### -AosServiceWebRootPath Path to the root folder where to locate the web.config file ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:AOSPath Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Flight, Flighting Author: Mötz Jensen (@Splaxi)) The DataAccess.FlightingServiceCatalogID must already be set in the web.config file. 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 ## RELATED LINKS ================================================ FILE: docs/Test-D365LabelIdIsValid.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Test-D365LabelIdIsValid ## SYNOPSIS Checks if a string is a valid 'Label Id' format ## SYNTAX ``` Test-D365LabelIdIsValid [-LabelId] [] ``` ## DESCRIPTION This function will validate if a string is a valid 'Label Id' format. ## EXAMPLES ### EXAMPLE 1 ``` Test-D365LabelIdIsValid -LabelId "ABC123" ``` This will test the if the LabelId is valid. It will use the "ABC123" as the LabelId parameter. The expected result is $true ### EXAMPLE 2 ``` Test-D365LabelIdIsValid -LabelId "@ABC123" ``` This will test the if the LabelId is valid. It will use the "@ABC123" as the LabelId parameter. The expected result is $true ### EXAMPLE 3 ``` Test-D365LabelIdIsValid -LabelId "@ABC123_1" ``` This will test the if the LabelId is valid. It will use the "@ABC123_1" as the LabelId parameter. The expected result is $false ### EXAMPLE 4 ``` Test-D365LabelIdIsValid -LabelId "ABC.123" #False ``` This will test the if the LabelId is valid. It will use the "ABC.123" as the LabelId parameter. The expected result is $false ## PARAMETERS ### -LabelId The LabelId string thay you want to validate ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ### System.Boolean ## NOTES Author: Alex Kwitny (@AlexOnDAX) The intent of this function is to be used with other methods to create valid labels via scripting. ## RELATED LINKS ================================================ FILE: docs/Update-D365BacpacModelFileSingleTable.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Update-D365BacpacModelFileSingleTable ## SYNOPSIS Update the "model.xml" from the bacpac file to a single table ## SYNTAX ``` Update-D365BacpacModelFileSingleTable [[-Path] ] [-Table] [[-Schema] ] [[-OutputPath] ] [-Force] [] ``` ## DESCRIPTION Update the "model.xml" file from inside the bacpac file to only handle a single table This can be used to restore a single table as fast as possible to a new data 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 The output can be used directly with the Import-D365Bacpac cmdlet and its ModelFile parameter, see the example sections for more details ## EXAMPLES ### EXAMPLE 1 ``` Update-D365BacpacModelFileSingleTable -Path "c:\temp\d365fo.tools\bacpac.model.xml" -Table "SalesTable" ``` This will create an updated bacpac.model.xml file with only the SalesTable to be imported. It will read the "c:\temp\d365fo.tools\bacpac.model.xml" file. It will use the default "dbo" as the Schema parameter. It will use the "SalesTable" as the Table parameter. It will use the "c:\temp\d365fo.tools\dbo.salestable.model.xml" as the default path for OutputPath parameter. ### EXAMPLE 2 ``` Update-D365BacpacModelFileSingleTable -Path "c:\temp\d365fo.tools\bacpac.model.xml" -Table "CommissionSalesGroup" -Schema "AX" ``` This will create an updated bacpac.model.xml file with only the "CommissionSalesGroup", from the "AX" schema, to be imported. It will read the "c:\temp\d365fo.tools\bacpac.model.xml" file. It will use the "AX" as the Schema for the table. It will use the "CommissionSalesGroup" as the Table parameter. It will use the "c:\temp\d365fo.tools\ax.CommissionSalesGroup.model.xml" as the default path for OutputPath parameter. ### EXAMPLE 3 ``` Update-D365BacpacModelFileSingleTable -Path "c:\temp\d365fo.tools\bacpac.model.xml" -Table "SalesTable" -OutputPath "c:\temp\troubleshoot.xml" ``` This will create an updated bacpac.model.xml file with only the SalesTable to be imported. It will read the "c:\temp\d365fo.tools\bacpac.model.xml" file. It will use the default "dbo" as the Schema parameter. It will use the "SalesTable" as the Table parameter. It will use the "c:\temp\troubleshoot.xml" as the path for OutputPath parameter. ### EXAMPLE 4 ``` Export-D365BacpacModelFile -Path "c:\Temp\AxDB.bacpac" | Update-D365BacpacModelFileSingleTable -Table SalesTable ``` This will create an updated bacpac.model.xml file with only the SalesTable to be imported. It will read the bacpac model file generated from the Export-D365BacpacModelFile cmdlet. It will use the default "dbo" as the Schema parameter. It will use the "SalesTable" as the Table parameter. It will use the "c:\temp\d365fo.tools\dbo.salestable.model.xml" as the default path for OutputPath parameter. ### EXAMPLE 5 ``` Update-D365BacpacModelFileSingleTable -Path "c:\temp\d365fo.tools\bacpac.model.xml" -Table "SalesTable" -Force ``` This will create an updated bacpac.model.xml file with only the SalesTable to be imported. It will read the "c:\temp\d365fo.tools\bacpac.model.xml" file. It will use the default "dbo" as the Schema parameter. It will use the "SalesTable" as the Table parameter. It will use the "c:\temp\d365fo.tools\dbo.salestable.model.xml" as the default path for OutputPath parameter. It will overwrite the "c:\temp\d365fo.tools\dbo.salestable.model.xml" if it already exists. ## PARAMETERS ### -Path Path to the bacpac file that you want to work against It can also be a zip file ```yaml Type: String Parameter Sets: (All) Aliases: File, ModelFile Required: False Position: 1 Default value: None Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -Table Name of the table that you want to be kept inside the model file when the update is done ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 2 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Schema Schema where the table that you want to work against exists The default value is "dbo" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: Dbo Accept pipeline input: False Accept wildcard characters: False ``` ### -OutputPath Path to where you want the updated bacpac model file to be saved Default value is: "c:\temp\d365fo.tools" ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DefaultTempPath Accept pipeline input: False Accept wildcard characters: False ``` ### -Force Switch to instruct the cmdlet to overwrite the bacpac model file specified in the OutputPath ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: False Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Tags: Bacpac, Servicing, Data, SqlPackage, Import, Table, Troubleshooting Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: docs/Update-D365User.md ================================================ --- external help file: d365fo.tools-help.xml Module Name: d365fo.tools online version: schema: 2.0.0 --- # Update-D365User ## SYNOPSIS Updates the user details in the database ## SYNTAX ``` Update-D365User [[-DatabaseServer] ] [[-DatabaseName] ] [[-SqlUser] ] [[-SqlPwd] ] [-Email] [[-Company] ] [] ``` ## DESCRIPTION Is capable of updating all the user details inside the UserInfo table to enable a user to sign in ## EXAMPLES ### EXAMPLE 1 ``` Update-D365User -Email "claire@contoso.com" ``` 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 ### EXAMPLE 2 ``` Update-D365User -Email "*contoso.com" ``` 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 ## PARAMETERS ### -DatabaseServer The name of the database server If on-premises or classic SQL Server, use either short name og Fully Qualified Domain Name (FQDN). If Azure use the full address to the database server, e.g. server.database.windows.net ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 1 Default value: $Script:DatabaseServer Accept pipeline input: False Accept wildcard characters: False ``` ### -DatabaseName The name of the database ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: $Script:DatabaseName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlUser The login name for the SQL Server instance ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 3 Default value: $Script:DatabaseUserName Accept pipeline input: False Accept wildcard characters: False ``` ### -SqlPwd The password for the SQL Server user ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 4 Default value: $Script:DatabaseUserPassword Accept pipeline input: False Accept wildcard characters: False ``` ### -Email The search string to select which user(s) should be updated. The parameter supports wildcards. E.g. -Email "*@contoso.com*" ```yaml Type: String Parameter Sets: (All) Aliases: Required: True Position: 5 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Company The company the user should start in. ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 6 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ## OUTPUTS ## NOTES Author: Rasmus Andersen (@ITRasmus) Author: Mötz Jensen (@Splaxi) ## RELATED LINKS ================================================ FILE: install.ps1 ================================================ <# .SYNOPSIS Installs the d365fo.tools Module from github .DESCRIPTION This script installs the d365fo.tools Module from github. It does so by ... - downloading the specified branch as zip to $env:TEMP - Unpacking that zip file to a folder in $env:TEMP - Moving that content to a module folder in either program files (default) or the user profile .PARAMETER Branch The branch to install. Installs master by default. Unknown branches will terminate the script in error. .PARAMETER UserMode The downloaded module will be moved to the user profile, rather than program files. .PARAMETER Force The install script will overwrite an existing module. #> [CmdletBinding()] Param ( [string] $Branch = "master", [switch] $UserMode, [switch] $Force ) #region Configuration for cloning script # Name of the module that is being cloned $ModuleName = "d365fo.tools" # Base path to the github repository $BaseUrl = "https://github.com/d365collaborative/d365fo.tools" # If the module is in a subfolder of the cloned repository, specify relative path here. Empty string to skip. $SubFolder = "d365fo.tools" #endregion Configuration for cloning script #region Parameter Calculation $doUserMode = $false if ($UserMode) { $doUserMode = $true } if ($install_CurrentUser) { $doUserMode = $true } if ($Scope -eq 'CurrentUser') { $doUserMode = $true } if ($install_Branch) { $Branch = $install_Branch } #endregion Parameter Calculation #region Utility Functions function Compress-Archive { <# .SYNOPSIS Creates an archive, or zipped file, from specified files and folders. .DESCRIPTION The 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. Because 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. .PARAMETER Path Specifies 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. .PARAMETER LiteralPath Specifies 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. .PARAMETER DestinationPath Specifies 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. .PARAMETER CompressionLevel Specifies 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: - Fastest. Use the fastest compression method available to decrease processing time; this can result in larger file sizes. - NoCompression. Do not compress the source files. - Optimal. Processing time is dependent on file size. If this parameter is not specified, the command uses the default value, Optimal. .PARAMETER Update Updates 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. .PARAMETER Force @{Text=} .PARAMETER Confirm Prompts you for confirmation before running the cmdlet. .PARAMETER WhatIf Shows what would happen if the cmdlet runs. The cmdlet is not run. .EXAMPLE Example 1: Create an archive file PS C:\>Compress-Archive -LiteralPath C:\Reference\Draftdoc.docx, C:\Reference\Images\diagram2.vsd -CompressionLevel Optimal -DestinationPath C:\Archives\Draft.Zip This 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. .EXAMPLE Example 2: Create an archive with wildcard characters PS C:\>Compress-Archive -Path C:\Reference\* -CompressionLevel Fastest -DestinationPath C:\Archives\Draft This 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. .EXAMPLE Example 3: Update an existing archive file PS C:\>Compress-Archive -Path C:\Reference\* -Update -DestinationPath C:\Archives\Draft.Zip This 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. .EXAMPLE Example 4: Create an archive from an entire folder PS C:\>Compress-Archive -Path C:\Reference -DestinationPath C:\Archives\Draft This 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. #> [CmdletBinding(DefaultParameterSetName = "Path", SupportsShouldProcess = $true, HelpUri = "http://go.microsoft.com/fwlink/?LinkID=393252")] param ( [parameter (mandatory = $true, Position = 0, ParameterSetName = "Path", ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [parameter (mandatory = $true, Position = 0, ParameterSetName = "PathWithForce", ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [parameter (mandatory = $true, Position = 0, ParameterSetName = "PathWithUpdate", ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [string[]] $Path, [parameter (mandatory = $true, ParameterSetName = "LiteralPath", ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)] [parameter (mandatory = $true, ParameterSetName = "LiteralPathWithForce", ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)] [parameter (mandatory = $true, ParameterSetName = "LiteralPathWithUpdate", ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [Alias("PSPath")] [string[]] $LiteralPath, [parameter (mandatory = $true, Position = 1, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $false)] [ValidateNotNullOrEmpty()] [string] $DestinationPath, [parameter ( mandatory = $false, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $false)] [ValidateSet("Optimal", "NoCompression", "Fastest")] [string] $CompressionLevel = "Optimal", [parameter(mandatory = $true, ParameterSetName = "PathWithUpdate", ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $false)] [parameter(mandatory = $true, ParameterSetName = "LiteralPathWithUpdate", ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $false)] [switch] $Update = $false, [parameter(mandatory = $true, ParameterSetName = "PathWithForce", ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $false)] [parameter(mandatory = $true, ParameterSetName = "LiteralPathWithForce", ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $false)] [switch] $Force = $false ) BEGIN { Add-Type -AssemblyName System.IO.Compression -ErrorAction Ignore Add-Type -AssemblyName System.IO.Compression.FileSystem -ErrorAction Ignore $zipFileExtension = ".zip" $LocalizedData = ConvertFrom-StringData @' PathNotFoundError=The path '{0}' either does not exist or is not a valid file system path. ExpandArchiveInValidDestinationPath=The path '{0}' is not a valid file system directory path. InvalidZipFileExtensionError={0} is not a supported archive file format. {1} is the only supported archive file format. ArchiveFileIsReadOnly=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. ZipFileExistError=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. DuplicatePathFoundError=The input to {0} parameter contains a duplicate path '{1}'. Provide a unique set of paths as input to {2} parameter. ArchiveFileIsEmpty=The archive file {0} is empty. CompressProgressBarText=The archive file '{0}' creation is in progress... ExpandProgressBarText=The archive file '{0}' expansion is in progress... AppendArchiveFileExtensionMessage=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}'. AddItemtoArchiveFile=Adding '{0}'. CreateFileAtExpandedPath=Created '{0}'. InvalidArchiveFilePathError=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. InvalidExpandedDirPathError=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. FileExistsError=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. DeleteArchiveFile=The partially created archive file '{0}' is deleted as it is not usable. InvalidDestinationPath=The destination path '{0}' does not contain a valid archive file name. PreparingToCompressVerboseMessage=Preparing to compress... PreparingToExpandVerboseMessage=Preparing to expand... '@ #region Utility Functions function GetResolvedPathHelper { param ( [string[]] $path, [boolean] $isLiteralPath, [System.Management.Automation.PSCmdlet] $callerPSCmdlet ) $resolvedPaths = @() # null and empty check are are already done on Path parameter at the cmdlet layer. foreach ($currentPath in $path) { try { if ($isLiteralPath) { $currentResolvedPaths = Resolve-Path -LiteralPath $currentPath -ErrorAction Stop } else { $currentResolvedPaths = Resolve-Path -Path $currentPath -ErrorAction Stop } } catch { $errorMessage = ($LocalizedData.PathNotFoundError -f $currentPath) $exception = New-Object System.InvalidOperationException $errorMessage, $_.Exception $errorRecord = CreateErrorRecordHelper "ArchiveCmdletPathNotFound" $null ([System.Management.Automation.ErrorCategory]::InvalidArgument) $exception $currentPath $callerPSCmdlet.ThrowTerminatingError($errorRecord) } foreach ($currentResolvedPath in $currentResolvedPaths) { $resolvedPaths += $currentResolvedPath.ProviderPath } } $resolvedPaths } function Add-CompressionAssemblies { if ($PSEdition -eq "Desktop") { Add-Type -AssemblyName System.IO.Compression Add-Type -AssemblyName System.IO.Compression.FileSystem } } function IsValidFileSystemPath { param ( [string[]] $path ) $result = $true; # null and empty check are are already done on Path parameter at the cmdlet layer. foreach ($currentPath in $path) { if (!([System.IO.File]::Exists($currentPath) -or [System.IO.Directory]::Exists($currentPath))) { $errorMessage = ($LocalizedData.PathNotFoundError -f $currentPath) ThrowTerminatingErrorHelper "PathNotFound" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $currentPath } } return $result; } function ValidateDuplicateFileSystemPath { param ( [string] $inputParameter, [string[]] $path ) $uniqueInputPaths = @() # null and empty check are are already done on Path parameter at the cmdlet layer. foreach ($currentPath in $path) { $currentInputPath = $currentPath.ToUpper() if ($uniqueInputPaths.Contains($currentInputPath)) { $errorMessage = ($LocalizedData.DuplicatePathFoundError -f $inputParameter, $currentPath, $inputParameter) ThrowTerminatingErrorHelper "DuplicatePathFound" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $currentPath } else { $uniqueInputPaths += $currentInputPath } } } function CompressionLevelMapper { param ( [string] $compressionLevel ) $compressionLevelFormat = [System.IO.Compression.CompressionLevel]::Optimal # CompressionLevel format is already validated at the cmdlet layer. switch ($compressionLevel.ToString()) { "Fastest" { $compressionLevelFormat = [System.IO.Compression.CompressionLevel]::Fastest } "NoCompression" { $compressionLevelFormat = [System.IO.Compression.CompressionLevel]::NoCompression } } return $compressionLevelFormat } function CompressArchiveHelper { param ( [string[]] $sourcePath, [string] $destinationPath, [string] $compressionLevel, [bool] $isUpdateMode ) $numberOfItemsArchived = 0 $sourceFilePaths = @() $sourceDirPaths = @() foreach ($currentPath in $sourcePath) { $result = Test-Path -LiteralPath $currentPath -PathType Leaf if ($result -eq $true) { $sourceFilePaths += $currentPath } else { $sourceDirPaths += $currentPath } } # The Soure Path contains one or more directory (this directory can have files under it) and no files to be compressed. if ($sourceFilePaths.Count -eq 0 -and $sourceDirPaths.Count -gt 0) { $currentSegmentWeight = 100/[double]$sourceDirPaths.Count $previousSegmentWeight = 0 foreach ($currentSourceDirPath in $sourceDirPaths) { $count = CompressSingleDirHelper $currentSourceDirPath $destinationPath $compressionLevel $true $isUpdateMode $previousSegmentWeight $currentSegmentWeight $numberOfItemsArchived += $count $previousSegmentWeight += $currentSegmentWeight } } # The Soure Path contains only files to be compressed. elseIf ($sourceFilePaths.Count -gt 0 -and $sourceDirPaths.Count -eq 0) { # $previousSegmentWeight is equal to 0 as there are no prior segments. # $currentSegmentWeight is set to 100 as all files have equal weightage. $previousSegmentWeight = 0 $currentSegmentWeight = 100 $numberOfItemsArchived = CompressFilesHelper $sourceFilePaths $destinationPath $compressionLevel $isUpdateMode $previousSegmentWeight $currentSegmentWeight } # The Soure Path contains one or more files and one or more directories (this directory can have files under it) to be compressed. elseif ($sourceFilePaths.Count -gt 0 -and $sourceDirPaths.Count -gt 0) { # each directory is considered as an individual segments & all the individual files are clubed in to a separate sgemnet. $currentSegmentWeight = 100/[double]($sourceDirPaths.Count + 1) $previousSegmentWeight = 0 foreach ($currentSourceDirPath in $sourceDirPaths) { $count = CompressSingleDirHelper $currentSourceDirPath $destinationPath $compressionLevel $true $isUpdateMode $previousSegmentWeight $currentSegmentWeight $numberOfItemsArchived += $count $previousSegmentWeight += $currentSegmentWeight } $count = CompressFilesHelper $sourceFilePaths $destinationPath $compressionLevel $isUpdateMode $previousSegmentWeight $currentSegmentWeight $numberOfItemsArchived += $count } return $numberOfItemsArchived } function CompressFilesHelper { param ( [string[]] $sourceFilePaths, [string] $destinationPath, [string] $compressionLevel, [bool] $isUpdateMode, [double] $previousSegmentWeight, [double] $currentSegmentWeight ) $numberOfItemsArchived = ZipArchiveHelper $sourceFilePaths $destinationPath $compressionLevel $isUpdateMode $null $previousSegmentWeight $currentSegmentWeight return $numberOfItemsArchived } function CompressSingleDirHelper { param ( [string] $sourceDirPath, [string] $destinationPath, [string] $compressionLevel, [bool] $useParentDirAsRoot, [bool] $isUpdateMode, [double] $previousSegmentWeight, [double] $currentSegmentWeight ) [System.Collections.Generic.List[System.String]]$subDirFiles = @() if ($useParentDirAsRoot) { $sourceDirInfo = New-Object -TypeName System.IO.DirectoryInfo -ArgumentList $sourceDirPath $sourceDirFullName = $sourceDirInfo.Parent.FullName # If the directory is present at the drive level the DirectoryInfo.Parent include '\' example: C:\ # On the other hand if the directory exists at a deper level then DirectoryInfo.Parent # has just the path (without an ending '\'). example C:\source if ($sourceDirFullName.Length -eq 3) { $modifiedSourceDirFullName = $sourceDirFullName } else { $modifiedSourceDirFullName = $sourceDirFullName + "\" } } else { $sourceDirFullName = $sourceDirPath $modifiedSourceDirFullName = $sourceDirFullName + "\" } $dirContents = Get-ChildItem -LiteralPath $sourceDirPath -Recurse foreach ($currentContent in $dirContents) { $isContainer = $currentContent -is [System.IO.DirectoryInfo] if (!$isContainer) { $subDirFiles.Add($currentContent.FullName) } else { # The currentContent points to a directory. # We need to check if the directory is an empty directory, if so such a # directory has to be explictly added to the archive file. # if there are no files in the directory the GetFiles() API returns an empty array. $files = $currentContent.GetFiles() if ($files.Count -eq 0) { $subDirFiles.Add($currentContent.FullName + "\") } } } $numberOfItemsArchived = ZipArchiveHelper $subDirFiles.ToArray() $destinationPath $compressionLevel $isUpdateMode $modifiedSourceDirFullName $previousSegmentWeight $currentSegmentWeight return $numberOfItemsArchived } function ZipArchiveHelper { param ( [System.Collections.Generic.List[System.String]] $sourcePaths, [string] $destinationPath, [string] $compressionLevel, [bool] $isUpdateMode, [string] $modifiedSourceDirFullName, [double] $previousSegmentWeight, [double] $currentSegmentWeight ) $numberOfItemsArchived = 0 $fileMode = [System.IO.FileMode]::Create $result = Test-Path -LiteralPath $DestinationPath -PathType Leaf if ($result -eq $true) { $fileMode = [System.IO.FileMode]::Open } Add-CompressionAssemblies try { # At this point we are sure that the archive file has write access. $archiveFileStreamArgs = @($destinationPath, $fileMode) $archiveFileStream = New-Object -TypeName System.IO.FileStream -ArgumentList $archiveFileStreamArgs $zipArchiveArgs = @($archiveFileStream, [System.IO.Compression.ZipArchiveMode]::Update, $false) $zipArchive = New-Object -TypeName System.IO.Compression.ZipArchive -ArgumentList $zipArchiveArgs $currentEntryCount = 0 $progressBarStatus = ($LocalizedData.CompressProgressBarText -f $destinationPath) $bufferSize = 4kb $buffer = New-Object Byte[] $bufferSize foreach ($currentFilePath in $sourcePaths) { if ($modifiedSourceDirFullName -ne $null -and $modifiedSourceDirFullName.Length -gt 0) { $index = $currentFilePath.IndexOf($modifiedSourceDirFullName, [System.StringComparison]::OrdinalIgnoreCase) $currentFilePathSubString = $currentFilePath.Substring($index, $modifiedSourceDirFullName.Length) $relativeFilePath = $currentFilePath.Replace($currentFilePathSubString, "").Trim() } else { $relativeFilePath = [System.IO.Path]::GetFileName($currentFilePath) } # Update mode is selected. # Check to see if archive file already contains one or more zip files in it. if ($isUpdateMode -eq $true -and $zipArchive.Entries.Count -gt 0) { $entryToBeUpdated = $null # Check if the file already exists in the archive file. # If so replace it with new file from the input source. # If the file does not exist in the archive file then default to # create mode and create the entry in the archive file. foreach ($currentArchiveEntry in $zipArchive.Entries) { if ($currentArchiveEntry.FullName -eq $relativeFilePath) { $entryToBeUpdated = $currentArchiveEntry break } } if ($entryToBeUpdated -ne $null) { $addItemtoArchiveFileMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentFilePath) $entryToBeUpdated.Delete() } } $compression = CompressionLevelMapper $compressionLevel # If a directory needs to be added to an archive file, # by convention the .Net API's expect the path of the diretcory # to end with '\' to detect the path as an directory. if (!$relativeFilePath.EndsWith("\", [StringComparison]::OrdinalIgnoreCase)) { try { try { $currentFileStream = [System.IO.File]::Open($currentFilePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) } catch { # Failed to access the file. Write a non terminating error to the pipeline # and move on with the remaining files. $exception = $_.Exception if ($null -ne $_.Exception -and $null -ne $_.Exception.InnerException) { $exception = $_.Exception.InnerException } $errorRecord = CreateErrorRecordHelper "CompressArchiveUnauthorizedAccessError" $null ([System.Management.Automation.ErrorCategory]::PermissionDenied) $exception $currentFilePath Write-Error -ErrorRecord $errorRecord } if ($null -ne $currentFileStream) { $srcStream = New-Object System.IO.BinaryReader $currentFileStream $currentArchiveEntry = $zipArchive.CreateEntry($relativeFilePath, $compression) # Updating the File Creation time so that the same timestamp would be retained after expanding the compressed file. # At this point we are sure that Get-ChildItem would succeed. $currentArchiveEntry.LastWriteTime = (Get-Item -LiteralPath $currentFilePath).LastWriteTime $destStream = New-Object System.IO.BinaryWriter $currentArchiveEntry.Open() while ($numberOfBytesRead = $srcStream.Read($buffer, 0, $bufferSize)) { $destStream.Write($buffer, 0, $numberOfBytesRead) $destStream.Flush() } $numberOfItemsArchived += 1 $addItemtoArchiveFileMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentFilePath) } } finally { If ($null -ne $currentFileStream) { $currentFileStream.Dispose() } If ($null -ne $srcStream) { $srcStream.Dispose() } If ($null -ne $destStream) { $destStream.Dispose() } } } else { $currentArchiveEntry = $zipArchive.CreateEntry("$relativeFilePath", $compression) $numberOfItemsArchived += 1 $addItemtoArchiveFileMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentFilePath) } if ($null -ne $addItemtoArchiveFileMessage) { Write-Verbose $addItemtoArchiveFileMessage } $currentEntryCount += 1 ProgressBarHelper "Compress-Archive" $progressBarStatus $previousSegmentWeight $currentSegmentWeight $sourcePaths.Count $currentEntryCount } } finally { If ($null -ne $zipArchive) { $zipArchive.Dispose() } If ($null -ne $archiveFileStream) { $archiveFileStream.Dispose() } # Complete writing progress. Write-Progress -Activity "Compress-Archive" -Completed } return $numberOfItemsArchived } <############################################################################################ # ValidateArchivePathHelper: This is a helper function used to validate the archive file # path & its file format. The only supported archive file format is .zip ############################################################################################> function ValidateArchivePathHelper { param ( [string] $archiveFile ) if ([System.IO.File]::Exists($archiveFile)) { $extension = [system.IO.Path]::GetExtension($archiveFile) # Invalid file extension is specifed for the zip file. if ($extension -ne $zipFileExtension) { $errorMessage = ($LocalizedData.InvalidZipFileExtensionError -f $extension, $zipFileExtension) ThrowTerminatingErrorHelper "NotSupportedArchiveFileExtension" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $extension } } else { $errorMessage = ($LocalizedData.PathNotFoundError -f $archiveFile) ThrowTerminatingErrorHelper "PathNotFound" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $archiveFile } } <############################################################################################ # ExpandArchiveHelper: This is a helper function used to expand the archive file contents # to the specified directory. ############################################################################################> function ExpandArchiveHelper { param ( [string] $archiveFile, [string] $expandedDir, [ref] $expandedItems, [boolean] $force, [boolean] $isVerbose, [boolean] $isConfirm ) Add-CompressionAssemblies try { # The existance of archive file has already been validated by ValidateArchivePathHelper # before calling this helper function. $archiveFileStreamArgs = @($archiveFile, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) $archiveFileStream = New-Object -TypeName System.IO.FileStream -ArgumentList $archiveFileStreamArgs $zipArchiveArgs = @($archiveFileStream, [System.IO.Compression.ZipArchiveMode]::Read, $false) $zipArchive = New-Object -TypeName System.IO.Compression.ZipArchive -ArgumentList $zipArchiveArgs if ($zipArchive.Entries.Count -eq 0) { $archiveFileIsEmpty = ($LocalizedData.ArchiveFileIsEmpty -f $archiveFile) Write-Verbose $archiveFileIsEmpty return } $currentEntryCount = 0 $progressBarStatus = ($LocalizedData.ExpandProgressBarText -f $archiveFile) # The archive entries can either be empty directories or files. foreach ($currentArchiveEntry in $zipArchive.Entries) { $currentArchiveEntryPath = Join-Path -Path $expandedDir -ChildPath $currentArchiveEntry.FullName $extension = [system.IO.Path]::GetExtension($currentArchiveEntryPath) # The current archive entry is an empty directory # The FullName of the Archive Entry representing a directory would end with a trailing '\'. if ($extension -eq [string]::Empty -and $currentArchiveEntryPath.EndsWith("\", [StringComparison]::OrdinalIgnoreCase)) { $pathExists = Test-Path -LiteralPath $currentArchiveEntryPath # The current archive entry expects an empty directory. # Check if the existing directory is empty. If its not empty # then it means that user has added this directory by other means. if ($pathExists -eq $false) { New-Item $currentArchiveEntryPath -ItemType Directory -Confirm:$isConfirm | Out-Null if (Test-Path -LiteralPath $currentArchiveEntryPath -PathType Container) { $addEmptyDirectorytoExpandedPathMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentArchiveEntryPath) Write-Verbose $addEmptyDirectorytoExpandedPathMessage $expandedItems.Value += $currentArchiveEntryPath } } } else { try { $currentArchiveEntryFileInfo = New-Object -TypeName System.IO.FileInfo -ArgumentList $currentArchiveEntryPath $parentDirExists = Test-Path -LiteralPath $currentArchiveEntryFileInfo.DirectoryName -PathType Container # If the Parent directory of the current entry in the archive file does not exist, then create it. if ($parentDirExists -eq $false) { New-Item $currentArchiveEntryFileInfo.DirectoryName -ItemType Directory -Confirm:$isConfirm | Out-Null if (!(Test-Path -LiteralPath $currentArchiveEntryFileInfo.DirectoryName -PathType Container)) { # The directory referred by $currentArchiveEntryFileInfo.DirectoryName was not successfully created. # This could be because the user has specified -Confirm paramter when Expand-Archive was invoked # and authorization was not provided when confirmation was prompted. In such a scenario, # we skip the current file in the archive and continue with the remaining archive file contents. Continue } $expandedItems.Value += $currentArchiveEntryFileInfo.DirectoryName } $hasNonTerminatingError = $false # Check if the file in to which the current archive entry contents # would be expanded already exists. if ($currentArchiveEntryFileInfo.Exists) { if ($force) { Remove-Item -LiteralPath $currentArchiveEntryFileInfo.FullName -Force -ErrorVariable ev -Verbose:$isVerbose -Confirm:$isConfirm if ($ev -ne $null) { $hasNonTerminatingError = $true } if (Test-Path -LiteralPath $currentArchiveEntryFileInfo.FullName -PathType Leaf) { # The file referred by $currentArchiveEntryFileInfo.FullName was not successfully removed. # This could be because the user has specified -Confirm paramter when Expand-Archive was invoked # and authorization was not provided when confirmation was prompted. In such a scenario, # we skip the current file in the archive and continue with the remaining archive file contents. Continue } } else { # Write non-terminating error to the pipeline. $errorMessage = ($LocalizedData.FileExistsError -f $currentArchiveEntryFileInfo.FullName, $archiveFile, $currentArchiveEntryFileInfo.FullName, $currentArchiveEntryFileInfo.FullName) $errorRecord = CreateErrorRecordHelper "ExpandArchiveFileExists" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidOperation) $null $currentArchiveEntryFileInfo.FullName Write-Error -ErrorRecord $errorRecord $hasNonTerminatingError = $true } } if (!$hasNonTerminatingError) { [System.IO.Compression.ZipFileExtensions]::ExtractToFile($currentArchiveEntry, $currentArchiveEntryPath, $false) # Add the expanded file path to the $expandedItems array, # to keep track of all the expanded files created while expanding the archive file. # If user enters CTRL + C then at that point of time, all these expanded files # would be deleted as part of the clean up process. $expandedItems.Value += $currentArchiveEntryPath $addFiletoExpandedPathMessage = ($LocalizedData.CreateFileAtExpandedPath -f $currentArchiveEntryPath) Write-Verbose $addFiletoExpandedPathMessage } } finally { If ($null -ne $destStream) { $destStream.Dispose() } If ($null -ne $srcStream) { $srcStream.Dispose() } } } $currentEntryCount += 1 # $currentSegmentWeight is Set to 100 giving equal weightage to each file that is getting expanded. # $previousSegmentWeight is set to 0 as there are no prior segments. $previousSegmentWeight = 0 $currentSegmentWeight = 100 ProgressBarHelper "Expand-Archive" $progressBarStatus $previousSegmentWeight $currentSegmentWeight $zipArchive.Entries.Count $currentEntryCount } } finally { If ($null -ne $zipArchive) { $zipArchive.Dispose() } If ($null -ne $archiveFileStream) { $archiveFileStream.Dispose() } # Complete writing progress. Write-Progress -Activity "Expand-Archive" -Completed } } <############################################################################################ # ProgressBarHelper: This is a helper function used to display progress message. # This function is used by both Compress-Archive & Expand-Archive to display archive file # creation/expansion progress. ############################################################################################> function ProgressBarHelper { param ( [string] $cmdletName, [string] $status, [double] $previousSegmentWeight, [double] $currentSegmentWeight, [int] $totalNumberofEntries, [int] $currentEntryCount ) if ($currentEntryCount -gt 0 -and $totalNumberofEntries -gt 0 -and $previousSegmentWeight -ge 0 -and $currentSegmentWeight -gt 0) { $entryDefaultWeight = $currentSegmentWeight/[double]$totalNumberofEntries $percentComplete = $previousSegmentWeight + ($entryDefaultWeight * $currentEntryCount) Write-Progress -Activity $cmdletName -Status $status -PercentComplete $percentComplete } } <############################################################################################ # CSVHelper: This is a helper function used to append comma after each path specifid by # the SourcePath array. This helper function is used to display all the user supplied paths # in the WhatIf message. ############################################################################################> function CSVHelper { param ( [string[]] $sourcePath ) # SourcePath has already been validated by the calling funcation. if ($sourcePath.Count -gt 1) { $sourcePathInCsvFormat = "`n" for ($currentIndex = 0; $currentIndex -lt $sourcePath.Count; $currentIndex++) { if ($currentIndex -eq $sourcePath.Count - 1) { $sourcePathInCsvFormat += $sourcePath[$currentIndex] } else { $sourcePathInCsvFormat += $sourcePath[$currentIndex] + "`n" } } } else { $sourcePathInCsvFormat = $sourcePath } return $sourcePathInCsvFormat } <############################################################################################ # ThrowTerminatingErrorHelper: This is a helper function used to throw terminating error. ############################################################################################> function ThrowTerminatingErrorHelper { param ( [string] $errorId, [string] $errorMessage, [System.Management.Automation.ErrorCategory] $errorCategory, [object] $targetObject, [Exception] $innerException ) if ($innerException -eq $null) { $exception = New-object System.IO.IOException $errorMessage } else { $exception = New-Object System.IO.IOException $errorMessage, $innerException } $exception = New-Object System.IO.IOException $errorMessage $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $targetObject $PSCmdlet.ThrowTerminatingError($errorRecord) } <############################################################################################ # CreateErrorRecordHelper: This is a helper function used to create an ErrorRecord ############################################################################################> function CreateErrorRecordHelper { param ( [string] $errorId, [string] $errorMessage, [System.Management.Automation.ErrorCategory] $errorCategory, [Exception] $exception, [object] $targetObject ) if ($null -eq $exception) { $exception = New-Object System.IO.IOException $errorMessage } $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $targetObject return $errorRecord } #endregion Utility Functions $inputPaths = @() $destinationParentDir = [system.IO.Path]::GetDirectoryName($DestinationPath) if ($null -eq $destinationParentDir) { $errorMessage = ($LocalizedData.InvalidDestinationPath -f $DestinationPath) ThrowTerminatingErrorHelper "InvalidArchiveFilePath" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $DestinationPath } if ($destinationParentDir -eq [string]::Empty) { $destinationParentDir = '.' } $achiveFileName = [system.IO.Path]::GetFileName($DestinationPath) $destinationParentDir = GetResolvedPathHelper $destinationParentDir $false $PSCmdlet if ($destinationParentDir.Count -gt 1) { $errorMessage = ($LocalizedData.InvalidArchiveFilePathError -f $DestinationPath, "DestinationPath", "DestinationPath") ThrowTerminatingErrorHelper "InvalidArchiveFilePath" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $DestinationPath } IsValidFileSystemPath $destinationParentDir | Out-Null $DestinationPath = Join-Path -Path $destinationParentDir -ChildPath $achiveFileName # GetExtension API does not validate for the actual existance of the path. $extension = [system.IO.Path]::GetExtension($DestinationPath) # If user does not specify .Zip extension, we append it. If ($extension -eq [string]::Empty) { $DestinationPathWithOutExtension = $DestinationPath $DestinationPath = $DestinationPathWithOutExtension + $zipFileExtension $appendArchiveFileExtensionMessage = ($LocalizedData.AppendArchiveFileExtensionMessage -f $DestinationPathWithOutExtension, $DestinationPath) Write-Verbose $appendArchiveFileExtensionMessage } else { # Invalid file extension is specified for the zip file to be created. if ($extension -ne $zipFileExtension) { $errorMessage = ($LocalizedData.InvalidZipFileExtensionError -f $extension, $zipFileExtension) ThrowTerminatingErrorHelper "NotSupportedArchiveFileExtension" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $extension } } $archiveFileExist = Test-Path -LiteralPath $DestinationPath -PathType Leaf if ($archiveFileExist -and ($Update -eq $false -and $Force -eq $false)) { $errorMessage = ($LocalizedData.ZipFileExistError -f $DestinationPath) ThrowTerminatingErrorHelper "ArchiveFileExists" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $DestinationPath } # If archive file already exists and if -Update is specified, then we check to see # if we have write access permission to update the existing archive file. if ($archiveFileExist -and $Update -eq $true) { $item = Get-Item -Path $DestinationPath if ($item.Attributes.ToString().Contains("ReadOnly")) { $errorMessage = ($LocalizedData.ArchiveFileIsReadOnly -f $DestinationPath) ThrowTerminatingErrorHelper "ArchiveFileIsReadOnly" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidOperation) $DestinationPath } } $isWhatIf = $psboundparameters.ContainsKey("WhatIf") if (!$isWhatIf) { $preparingToCompressVerboseMessage = ($LocalizedData.PreparingToCompressVerboseMessage) Write-Verbose $preparingToCompressVerboseMessage $progressBarStatus = ($LocalizedData.CompressProgressBarText -f $DestinationPath) ProgressBarHelper "Compress-Archive" $progressBarStatus 0 100 100 1 } } PROCESS { if ($PsCmdlet.ParameterSetName -eq "Path" -or $PsCmdlet.ParameterSetName -eq "PathWithForce" -or $PsCmdlet.ParameterSetName -eq "PathWithUpdate") { $inputPaths += $Path } if ($PsCmdlet.ParameterSetName -eq "LiteralPath" -or $PsCmdlet.ParameterSetName -eq "LiteralPathWithForce" -or $PsCmdlet.ParameterSetName -eq "LiteralPathWithUpdate") { $inputPaths += $LiteralPath } } END { # If archive file already exists and if -Force is specified, we delete the # existing artchive file and create a brand new one. if (($PsCmdlet.ParameterSetName -eq "PathWithForce" -or $PsCmdlet.ParameterSetName -eq "LiteralPathWithForce") -and $archiveFileExist) { Remove-Item -Path $DestinationPath -Force -ErrorAction Stop } # Validate Source Path depeding on parameter set being used. # The specified source path conatins one or more files or directories that needs # to be compressed. $isLiteralPathUsed = $false if ($PsCmdlet.ParameterSetName -eq "LiteralPath" -or $PsCmdlet.ParameterSetName -eq "LiteralPathWithForce" -or $PsCmdlet.ParameterSetName -eq "LiteralPathWithUpdate") { $isLiteralPathUsed = $true } ValidateDuplicateFileSystemPath $PsCmdlet.ParameterSetName $inputPaths $resolvedPaths = GetResolvedPathHelper $inputPaths $isLiteralPathUsed $PSCmdlet IsValidFileSystemPath $resolvedPaths | Out-Null $sourcePath = $resolvedPaths; # CSVHelper: This is a helper function used to append comma after each path specifid by # the $sourcePath array. The comma saperated paths are displayed in the -WhatIf message. $sourcePathInCsvFormat = CSVHelper $sourcePath if ($pscmdlet.ShouldProcess($sourcePathInCsvFormat)) { try { # StopProcessing is not avaliable in Script cmdlets. However the pipleline execution # is terminated when ever 'CTRL + C' is entered by user to terminate the cmdlet execution. # The finally block is executed whenever pipleline is terminated. # $isArchiveFileProcessingComplete variable is used to track if 'CTRL + C' is entered by the # user. $isArchiveFileProcessingComplete = $false $numberOfItemsArchived = CompressArchiveHelper $sourcePath $DestinationPath $CompressionLevel $Update $isArchiveFileProcessingComplete = $true } finally { # The $isArchiveFileProcessingComplete would be set to $false if user has typed 'CTRL + C' to # terminate the cmdlet execution or if an unhandled exception is thrown. # $numberOfItemsArchived contains the count of number of files or directories add to the archive file. # If the newly created archive file is empty then we delete it as its not usable. if (($isArchiveFileProcessingComplete -eq $false) -or ($numberOfItemsArchived -eq 0)) { $DeleteArchiveFileMessage = ($LocalizedData.DeleteArchiveFile -f $DestinationPath) Write-Verbose $DeleteArchiveFileMessage # delete the partial archive file created. if (Test-Path $DestinationPath) { Remove-Item -LiteralPath $DestinationPath -Force -Recurse -ErrorAction SilentlyContinue } } } } } } function Expand-Archive { <# .SYNOPSIS Extracts files from a specified archive (zipped) file. .DESCRIPTION The 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. .PARAMETER Path Specifies the path to the archive file. .PARAMETER LiteralPath Specifies 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. .PARAMETER DestinationPath Specifies 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. .PARAMETER Force Forces the command to run without asking for user confirmation. .PARAMETER Confirm Prompts you for confirmation before running the cmdlet. .PARAMETER WhatIf Shows what would happen if the cmdlet runs. The cmdlet is not run. .EXAMPLE Example 1: Extract the contents of an archive PS C:\>Expand-Archive -LiteralPath C:\Archives\Draft.Zip -DestinationPath C:\Reference This command extracts the contents of an existing archive file, Draft.zip, into the folder specified by the DestinationPath parameter, C:\Reference. .EXAMPLE Example 2: Extract the contents of an archive in the current folder PS C:\>Expand-Archive -Path Draft.Zip -DestinationPath C:\Reference This 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. #> [CmdletBinding( DefaultParameterSetName = "Path", SupportsShouldProcess = $true, HelpUri = "http://go.microsoft.com/fwlink/?LinkID=393253")] param ( [parameter ( mandatory = $true, Position = 0, ParameterSetName = "Path", ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [string] $Path, [parameter ( mandatory = $true, ParameterSetName = "LiteralPath", ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [Alias("PSPath")] [string] $LiteralPath, [parameter (mandatory = $false, Position = 1, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $false)] [ValidateNotNullOrEmpty()] [string] $DestinationPath, [parameter (mandatory = $false, ValueFromPipeline = $false, ValueFromPipelineByPropertyName = $false)] [switch] $Force ) BEGIN { Add-Type -AssemblyName System.IO.Compression -ErrorAction Ignore Add-Type -AssemblyName System.IO.Compression.FileSystem -ErrorAction Ignore $zipFileExtension = ".zip" $LocalizedData = ConvertFrom-StringData @' PathNotFoundError=The path '{0}' either does not exist or is not a valid file system path. ExpandArchiveInValidDestinationPath=The path '{0}' is not a valid file system directory path. InvalidZipFileExtensionError={0} is not a supported archive file format. {1} is the only supported archive file format. ArchiveFileIsReadOnly=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. ZipFileExistError=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. DuplicatePathFoundError=The input to {0} parameter contains a duplicate path '{1}'. Provide a unique set of paths as input to {2} parameter. ArchiveFileIsEmpty=The archive file {0} is empty. CompressProgressBarText=The archive file '{0}' creation is in progress... ExpandProgressBarText=The archive file '{0}' expansion is in progress... AppendArchiveFileExtensionMessage=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}'. AddItemtoArchiveFile=Adding '{0}'. CreateFileAtExpandedPath=Created '{0}'. InvalidArchiveFilePathError=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. InvalidExpandedDirPathError=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. FileExistsError=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. DeleteArchiveFile=The partially created archive file '{0}' is deleted as it is not usable. InvalidDestinationPath=The destination path '{0}' does not contain a valid archive file name. PreparingToCompressVerboseMessage=Preparing to compress... PreparingToExpandVerboseMessage=Preparing to expand... '@ #region Utility Functions function GetResolvedPathHelper { param ( [string[]] $path, [boolean] $isLiteralPath, [System.Management.Automation.PSCmdlet] $callerPSCmdlet ) $resolvedPaths = @() # null and empty check are are already done on Path parameter at the cmdlet layer. foreach ($currentPath in $path) { try { if ($isLiteralPath) { $currentResolvedPaths = Resolve-Path -LiteralPath $currentPath -ErrorAction Stop } else { $currentResolvedPaths = Resolve-Path -Path $currentPath -ErrorAction Stop } } catch { $errorMessage = ($LocalizedData.PathNotFoundError -f $currentPath) $exception = New-Object System.InvalidOperationException $errorMessage, $_.Exception $errorRecord = CreateErrorRecordHelper "ArchiveCmdletPathNotFound" $null ([System.Management.Automation.ErrorCategory]::InvalidArgument) $exception $currentPath $callerPSCmdlet.ThrowTerminatingError($errorRecord) } foreach ($currentResolvedPath in $currentResolvedPaths) { $resolvedPaths += $currentResolvedPath.ProviderPath } } $resolvedPaths } function Add-CompressionAssemblies { if ($PSEdition -eq "Desktop") { Add-Type -AssemblyName System.IO.Compression Add-Type -AssemblyName System.IO.Compression.FileSystem } } function IsValidFileSystemPath { param ( [string[]] $path ) $result = $true; # null and empty check are are already done on Path parameter at the cmdlet layer. foreach ($currentPath in $path) { if (!([System.IO.File]::Exists($currentPath) -or [System.IO.Directory]::Exists($currentPath))) { $errorMessage = ($LocalizedData.PathNotFoundError -f $currentPath) ThrowTerminatingErrorHelper "PathNotFound" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $currentPath } } return $result; } function ValidateDuplicateFileSystemPath { param ( [string] $inputParameter, [string[]] $path ) $uniqueInputPaths = @() # null and empty check are are already done on Path parameter at the cmdlet layer. foreach ($currentPath in $path) { $currentInputPath = $currentPath.ToUpper() if ($uniqueInputPaths.Contains($currentInputPath)) { $errorMessage = ($LocalizedData.DuplicatePathFoundError -f $inputParameter, $currentPath, $inputParameter) ThrowTerminatingErrorHelper "DuplicatePathFound" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $currentPath } else { $uniqueInputPaths += $currentInputPath } } } function CompressionLevelMapper { param ( [string] $compressionLevel ) $compressionLevelFormat = [System.IO.Compression.CompressionLevel]::Optimal # CompressionLevel format is already validated at the cmdlet layer. switch ($compressionLevel.ToString()) { "Fastest" { $compressionLevelFormat = [System.IO.Compression.CompressionLevel]::Fastest } "NoCompression" { $compressionLevelFormat = [System.IO.Compression.CompressionLevel]::NoCompression } } return $compressionLevelFormat } function CompressArchiveHelper { param ( [string[]] $sourcePath, [string] $destinationPath, [string] $compressionLevel, [bool] $isUpdateMode ) $numberOfItemsArchived = 0 $sourceFilePaths = @() $sourceDirPaths = @() foreach ($currentPath in $sourcePath) { $result = Test-Path -LiteralPath $currentPath -PathType Leaf if ($result -eq $true) { $sourceFilePaths += $currentPath } else { $sourceDirPaths += $currentPath } } # The Soure Path contains one or more directory (this directory can have files under it) and no files to be compressed. if ($sourceFilePaths.Count -eq 0 -and $sourceDirPaths.Count -gt 0) { $currentSegmentWeight = 100/[double]$sourceDirPaths.Count $previousSegmentWeight = 0 foreach ($currentSourceDirPath in $sourceDirPaths) { $count = CompressSingleDirHelper $currentSourceDirPath $destinationPath $compressionLevel $true $isUpdateMode $previousSegmentWeight $currentSegmentWeight $numberOfItemsArchived += $count $previousSegmentWeight += $currentSegmentWeight } } # The Soure Path contains only files to be compressed. elseIf ($sourceFilePaths.Count -gt 0 -and $sourceDirPaths.Count -eq 0) { # $previousSegmentWeight is equal to 0 as there are no prior segments. # $currentSegmentWeight is set to 100 as all files have equal weightage. $previousSegmentWeight = 0 $currentSegmentWeight = 100 $numberOfItemsArchived = CompressFilesHelper $sourceFilePaths $destinationPath $compressionLevel $isUpdateMode $previousSegmentWeight $currentSegmentWeight } # The Soure Path contains one or more files and one or more directories (this directory can have files under it) to be compressed. elseif ($sourceFilePaths.Count -gt 0 -and $sourceDirPaths.Count -gt 0) { # each directory is considered as an individual segments & all the individual files are clubed in to a separate sgemnet. $currentSegmentWeight = 100/[double]($sourceDirPaths.Count + 1) $previousSegmentWeight = 0 foreach ($currentSourceDirPath in $sourceDirPaths) { $count = CompressSingleDirHelper $currentSourceDirPath $destinationPath $compressionLevel $true $isUpdateMode $previousSegmentWeight $currentSegmentWeight $numberOfItemsArchived += $count $previousSegmentWeight += $currentSegmentWeight } $count = CompressFilesHelper $sourceFilePaths $destinationPath $compressionLevel $isUpdateMode $previousSegmentWeight $currentSegmentWeight $numberOfItemsArchived += $count } return $numberOfItemsArchived } function CompressFilesHelper { param ( [string[]] $sourceFilePaths, [string] $destinationPath, [string] $compressionLevel, [bool] $isUpdateMode, [double] $previousSegmentWeight, [double] $currentSegmentWeight ) $numberOfItemsArchived = ZipArchiveHelper $sourceFilePaths $destinationPath $compressionLevel $isUpdateMode $null $previousSegmentWeight $currentSegmentWeight return $numberOfItemsArchived } function CompressSingleDirHelper { param ( [string] $sourceDirPath, [string] $destinationPath, [string] $compressionLevel, [bool] $useParentDirAsRoot, [bool] $isUpdateMode, [double] $previousSegmentWeight, [double] $currentSegmentWeight ) [System.Collections.Generic.List[System.String]]$subDirFiles = @() if ($useParentDirAsRoot) { $sourceDirInfo = New-Object -TypeName System.IO.DirectoryInfo -ArgumentList $sourceDirPath $sourceDirFullName = $sourceDirInfo.Parent.FullName # If the directory is present at the drive level the DirectoryInfo.Parent include '\' example: C:\ # On the other hand if the directory exists at a deper level then DirectoryInfo.Parent # has just the path (without an ending '\'). example C:\source if ($sourceDirFullName.Length -eq 3) { $modifiedSourceDirFullName = $sourceDirFullName } else { $modifiedSourceDirFullName = $sourceDirFullName + "\" } } else { $sourceDirFullName = $sourceDirPath $modifiedSourceDirFullName = $sourceDirFullName + "\" } $dirContents = Get-ChildItem -LiteralPath $sourceDirPath -Recurse foreach ($currentContent in $dirContents) { $isContainer = $currentContent -is [System.IO.DirectoryInfo] if (!$isContainer) { $subDirFiles.Add($currentContent.FullName) } else { # The currentContent points to a directory. # We need to check if the directory is an empty directory, if so such a # directory has to be explictly added to the archive file. # if there are no files in the directory the GetFiles() API returns an empty array. $files = $currentContent.GetFiles() if ($files.Count -eq 0) { $subDirFiles.Add($currentContent.FullName + "\") } } } $numberOfItemsArchived = ZipArchiveHelper $subDirFiles.ToArray() $destinationPath $compressionLevel $isUpdateMode $modifiedSourceDirFullName $previousSegmentWeight $currentSegmentWeight return $numberOfItemsArchived } function ZipArchiveHelper { param ( [System.Collections.Generic.List[System.String]] $sourcePaths, [string] $destinationPath, [string] $compressionLevel, [bool] $isUpdateMode, [string] $modifiedSourceDirFullName, [double] $previousSegmentWeight, [double] $currentSegmentWeight ) $numberOfItemsArchived = 0 $fileMode = [System.IO.FileMode]::Create $result = Test-Path -LiteralPath $DestinationPath -PathType Leaf if ($result -eq $true) { $fileMode = [System.IO.FileMode]::Open } Add-CompressionAssemblies try { # At this point we are sure that the archive file has write access. $archiveFileStreamArgs = @($destinationPath, $fileMode) $archiveFileStream = New-Object -TypeName System.IO.FileStream -ArgumentList $archiveFileStreamArgs $zipArchiveArgs = @($archiveFileStream, [System.IO.Compression.ZipArchiveMode]::Update, $false) $zipArchive = New-Object -TypeName System.IO.Compression.ZipArchive -ArgumentList $zipArchiveArgs $currentEntryCount = 0 $progressBarStatus = ($LocalizedData.CompressProgressBarText -f $destinationPath) $bufferSize = 4kb $buffer = New-Object Byte[] $bufferSize foreach ($currentFilePath in $sourcePaths) { if ($modifiedSourceDirFullName -ne $null -and $modifiedSourceDirFullName.Length -gt 0) { $index = $currentFilePath.IndexOf($modifiedSourceDirFullName, [System.StringComparison]::OrdinalIgnoreCase) $currentFilePathSubString = $currentFilePath.Substring($index, $modifiedSourceDirFullName.Length) $relativeFilePath = $currentFilePath.Replace($currentFilePathSubString, "").Trim() } else { $relativeFilePath = [System.IO.Path]::GetFileName($currentFilePath) } # Update mode is selected. # Check to see if archive file already contains one or more zip files in it. if ($isUpdateMode -eq $true -and $zipArchive.Entries.Count -gt 0) { $entryToBeUpdated = $null # Check if the file already exists in the archive file. # If so replace it with new file from the input source. # If the file does not exist in the archive file then default to # create mode and create the entry in the archive file. foreach ($currentArchiveEntry in $zipArchive.Entries) { if ($currentArchiveEntry.FullName -eq $relativeFilePath) { $entryToBeUpdated = $currentArchiveEntry break } } if ($entryToBeUpdated -ne $null) { $addItemtoArchiveFileMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentFilePath) $entryToBeUpdated.Delete() } } $compression = CompressionLevelMapper $compressionLevel # If a directory needs to be added to an archive file, # by convention the .Net API's expect the path of the diretcory # to end with '\' to detect the path as an directory. if (!$relativeFilePath.EndsWith("\", [StringComparison]::OrdinalIgnoreCase)) { try { try { $currentFileStream = [System.IO.File]::Open($currentFilePath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) } catch { # Failed to access the file. Write a non terminating error to the pipeline # and move on with the remaining files. $exception = $_.Exception if ($null -ne $_.Exception -and $null -ne $_.Exception.InnerException) { $exception = $_.Exception.InnerException } $errorRecord = CreateErrorRecordHelper "CompressArchiveUnauthorizedAccessError" $null ([System.Management.Automation.ErrorCategory]::PermissionDenied) $exception $currentFilePath Write-Error -ErrorRecord $errorRecord } if ($null -ne $currentFileStream) { $srcStream = New-Object System.IO.BinaryReader $currentFileStream $currentArchiveEntry = $zipArchive.CreateEntry($relativeFilePath, $compression) # Updating the File Creation time so that the same timestamp would be retained after expanding the compressed file. # At this point we are sure that Get-ChildItem would succeed. $currentArchiveEntry.LastWriteTime = (Get-Item -LiteralPath $currentFilePath).LastWriteTime $destStream = New-Object System.IO.BinaryWriter $currentArchiveEntry.Open() while ($numberOfBytesRead = $srcStream.Read($buffer, 0, $bufferSize)) { $destStream.Write($buffer, 0, $numberOfBytesRead) $destStream.Flush() } $numberOfItemsArchived += 1 $addItemtoArchiveFileMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentFilePath) } } finally { If ($null -ne $currentFileStream) { $currentFileStream.Dispose() } If ($null -ne $srcStream) { $srcStream.Dispose() } If ($null -ne $destStream) { $destStream.Dispose() } } } else { $currentArchiveEntry = $zipArchive.CreateEntry("$relativeFilePath", $compression) $numberOfItemsArchived += 1 $addItemtoArchiveFileMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentFilePath) } if ($null -ne $addItemtoArchiveFileMessage) { Write-Verbose $addItemtoArchiveFileMessage } $currentEntryCount += 1 ProgressBarHelper "Compress-Archive" $progressBarStatus $previousSegmentWeight $currentSegmentWeight $sourcePaths.Count $currentEntryCount } } finally { If ($null -ne $zipArchive) { $zipArchive.Dispose() } If ($null -ne $archiveFileStream) { $archiveFileStream.Dispose() } # Complete writing progress. Write-Progress -Activity "Compress-Archive" -Completed } return $numberOfItemsArchived } <############################################################################################ # ValidateArchivePathHelper: This is a helper function used to validate the archive file # path & its file format. The only supported archive file format is .zip ############################################################################################> function ValidateArchivePathHelper { param ( [string] $archiveFile ) if ([System.IO.File]::Exists($archiveFile)) { $extension = [system.IO.Path]::GetExtension($archiveFile) # Invalid file extension is specifed for the zip file. if ($extension -ne $zipFileExtension) { $errorMessage = ($LocalizedData.InvalidZipFileExtensionError -f $extension, $zipFileExtension) ThrowTerminatingErrorHelper "NotSupportedArchiveFileExtension" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $extension } } else { $errorMessage = ($LocalizedData.PathNotFoundError -f $archiveFile) ThrowTerminatingErrorHelper "PathNotFound" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $archiveFile } } <############################################################################################ # ExpandArchiveHelper: This is a helper function used to expand the archive file contents # to the specified directory. ############################################################################################> function ExpandArchiveHelper { param ( [string] $archiveFile, [string] $expandedDir, [ref] $expandedItems, [boolean] $force, [boolean] $isVerbose, [boolean] $isConfirm ) Add-CompressionAssemblies try { # The existance of archive file has already been validated by ValidateArchivePathHelper # before calling this helper function. $archiveFileStreamArgs = @($archiveFile, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read) $archiveFileStream = New-Object -TypeName System.IO.FileStream -ArgumentList $archiveFileStreamArgs $zipArchiveArgs = @($archiveFileStream, [System.IO.Compression.ZipArchiveMode]::Read, $false) $zipArchive = New-Object -TypeName System.IO.Compression.ZipArchive -ArgumentList $zipArchiveArgs if ($zipArchive.Entries.Count -eq 0) { $archiveFileIsEmpty = ($LocalizedData.ArchiveFileIsEmpty -f $archiveFile) Write-Verbose $archiveFileIsEmpty return } $currentEntryCount = 0 $progressBarStatus = ($LocalizedData.ExpandProgressBarText -f $archiveFile) # The archive entries can either be empty directories or files. foreach ($currentArchiveEntry in $zipArchive.Entries) { $currentArchiveEntryPath = Join-Path -Path $expandedDir -ChildPath $currentArchiveEntry.FullName $extension = [system.IO.Path]::GetExtension($currentArchiveEntryPath) # The current archive entry is an empty directory # The FullName of the Archive Entry representing a directory would end with a trailing '\'. if ($extension -eq [string]::Empty -and $currentArchiveEntryPath.EndsWith("\", [StringComparison]::OrdinalIgnoreCase)) { $pathExists = Test-Path -LiteralPath $currentArchiveEntryPath # The current archive entry expects an empty directory. # Check if the existing directory is empty. If its not empty # then it means that user has added this directory by other means. if ($pathExists -eq $false) { New-Item $currentArchiveEntryPath -ItemType Directory -Confirm:$isConfirm | Out-Null if (Test-Path -LiteralPath $currentArchiveEntryPath -PathType Container) { $addEmptyDirectorytoExpandedPathMessage = ($LocalizedData.AddItemtoArchiveFile -f $currentArchiveEntryPath) Write-Verbose $addEmptyDirectorytoExpandedPathMessage $expandedItems.Value += $currentArchiveEntryPath } } } else { try { $currentArchiveEntryFileInfo = New-Object -TypeName System.IO.FileInfo -ArgumentList $currentArchiveEntryPath $parentDirExists = Test-Path -LiteralPath $currentArchiveEntryFileInfo.DirectoryName -PathType Container # If the Parent directory of the current entry in the archive file does not exist, then create it. if ($parentDirExists -eq $false) { New-Item $currentArchiveEntryFileInfo.DirectoryName -ItemType Directory -Confirm:$isConfirm | Out-Null if (!(Test-Path -LiteralPath $currentArchiveEntryFileInfo.DirectoryName -PathType Container)) { # The directory referred by $currentArchiveEntryFileInfo.DirectoryName was not successfully created. # This could be because the user has specified -Confirm paramter when Expand-Archive was invoked # and authorization was not provided when confirmation was prompted. In such a scenario, # we skip the current file in the archive and continue with the remaining archive file contents. Continue } $expandedItems.Value += $currentArchiveEntryFileInfo.DirectoryName } $hasNonTerminatingError = $false # Check if the file in to which the current archive entry contents # would be expanded already exists. if ($currentArchiveEntryFileInfo.Exists) { if ($force) { Remove-Item -LiteralPath $currentArchiveEntryFileInfo.FullName -Force -ErrorVariable ev -Verbose:$isVerbose -Confirm:$isConfirm if ($ev -ne $null) { $hasNonTerminatingError = $true } if (Test-Path -LiteralPath $currentArchiveEntryFileInfo.FullName -PathType Leaf) { # The file referred by $currentArchiveEntryFileInfo.FullName was not successfully removed. # This could be because the user has specified -Confirm paramter when Expand-Archive was invoked # and authorization was not provided when confirmation was prompted. In such a scenario, # we skip the current file in the archive and continue with the remaining archive file contents. Continue } } else { # Write non-terminating error to the pipeline. $errorMessage = ($LocalizedData.FileExistsError -f $currentArchiveEntryFileInfo.FullName, $archiveFile, $currentArchiveEntryFileInfo.FullName, $currentArchiveEntryFileInfo.FullName) $errorRecord = CreateErrorRecordHelper "ExpandArchiveFileExists" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidOperation) $null $currentArchiveEntryFileInfo.FullName Write-Error -ErrorRecord $errorRecord $hasNonTerminatingError = $true } } if (!$hasNonTerminatingError) { [System.IO.Compression.ZipFileExtensions]::ExtractToFile($currentArchiveEntry, $currentArchiveEntryPath, $false) # Add the expanded file path to the $expandedItems array, # to keep track of all the expanded files created while expanding the archive file. # If user enters CTRL + C then at that point of time, all these expanded files # would be deleted as part of the clean up process. $expandedItems.Value += $currentArchiveEntryPath $addFiletoExpandedPathMessage = ($LocalizedData.CreateFileAtExpandedPath -f $currentArchiveEntryPath) Write-Verbose $addFiletoExpandedPathMessage } } finally { If ($null -ne $destStream) { $destStream.Dispose() } If ($null -ne $srcStream) { $srcStream.Dispose() } } } $currentEntryCount += 1 # $currentSegmentWeight is Set to 100 giving equal weightage to each file that is getting expanded. # $previousSegmentWeight is set to 0 as there are no prior segments. $previousSegmentWeight = 0 $currentSegmentWeight = 100 ProgressBarHelper "Expand-Archive" $progressBarStatus $previousSegmentWeight $currentSegmentWeight $zipArchive.Entries.Count $currentEntryCount } } finally { If ($null -ne $zipArchive) { $zipArchive.Dispose() } If ($null -ne $archiveFileStream) { $archiveFileStream.Dispose() } # Complete writing progress. Write-Progress -Activity "Expand-Archive" -Completed } } <############################################################################################ # ProgressBarHelper: This is a helper function used to display progress message. # This function is used by both Compress-Archive & Expand-Archive to display archive file # creation/expansion progress. ############################################################################################> function ProgressBarHelper { param ( [string] $cmdletName, [string] $status, [double] $previousSegmentWeight, [double] $currentSegmentWeight, [int] $totalNumberofEntries, [int] $currentEntryCount ) if ($currentEntryCount -gt 0 -and $totalNumberofEntries -gt 0 -and $previousSegmentWeight -ge 0 -and $currentSegmentWeight -gt 0) { $entryDefaultWeight = $currentSegmentWeight/[double]$totalNumberofEntries $percentComplete = $previousSegmentWeight + ($entryDefaultWeight * $currentEntryCount) Write-Progress -Activity $cmdletName -Status $status -PercentComplete $percentComplete } } <############################################################################################ # CSVHelper: This is a helper function used to append comma after each path specifid by # the SourcePath array. This helper function is used to display all the user supplied paths # in the WhatIf message. ############################################################################################> function CSVHelper { param ( [string[]] $sourcePath ) # SourcePath has already been validated by the calling funcation. if ($sourcePath.Count -gt 1) { $sourcePathInCsvFormat = "`n" for ($currentIndex = 0; $currentIndex -lt $sourcePath.Count; $currentIndex++) { if ($currentIndex -eq $sourcePath.Count - 1) { $sourcePathInCsvFormat += $sourcePath[$currentIndex] } else { $sourcePathInCsvFormat += $sourcePath[$currentIndex] + "`n" } } } else { $sourcePathInCsvFormat = $sourcePath } return $sourcePathInCsvFormat } <############################################################################################ # ThrowTerminatingErrorHelper: This is a helper function used to throw terminating error. ############################################################################################> function ThrowTerminatingErrorHelper { param ( [string] $errorId, [string] $errorMessage, [System.Management.Automation.ErrorCategory] $errorCategory, [object] $targetObject, [Exception] $innerException ) if ($innerException -eq $null) { $exception = New-object System.IO.IOException $errorMessage } else { $exception = New-Object System.IO.IOException $errorMessage, $innerException } $exception = New-Object System.IO.IOException $errorMessage $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $targetObject $PSCmdlet.ThrowTerminatingError($errorRecord) } <############################################################################################ # CreateErrorRecordHelper: This is a helper function used to create an ErrorRecord ############################################################################################> function CreateErrorRecordHelper { param ( [string] $errorId, [string] $errorMessage, [System.Management.Automation.ErrorCategory] $errorCategory, [Exception] $exception, [object] $targetObject ) if ($null -eq $exception) { $exception = New-Object System.IO.IOException $errorMessage } $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $targetObject return $errorRecord } #endregion Utility Functions $isVerbose = $psboundparameters.ContainsKey("Verbose") $isConfirm = $psboundparameters.ContainsKey("Confirm") $isDestinationPathProvided = $true if ($DestinationPath -eq [string]::Empty) { $resolvedDestinationPath = $pwd $isDestinationPathProvided = $false } else { $destinationPathExists = Test-Path -Path $DestinationPath -PathType Container if ($destinationPathExists) { $resolvedDestinationPath = GetResolvedPathHelper $DestinationPath $false $PSCmdlet if ($resolvedDestinationPath.Count -gt 1) { $errorMessage = ($LocalizedData.InvalidExpandedDirPathError -f $DestinationPath) ThrowTerminatingErrorHelper "InvalidDestinationPath" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $DestinationPath } # At this point we are sure that the provided path resolves to a valid single path. # Calling Resolve-Path again to get the underlying provider name. $suppliedDestinationPath = Resolve-Path -Path $DestinationPath if ($suppliedDestinationPath.Provider.Name -ne "FileSystem") { $errorMessage = ($LocalizedData.ExpandArchiveInValidDestinationPath -f $DestinationPath) ThrowTerminatingErrorHelper "InvalidDirectoryPath" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $DestinationPath } } else { $createdItem = New-Item -Path $DestinationPath -ItemType Directory -Confirm:$isConfirm -Verbose:$isVerbose -ErrorAction Stop if ($createdItem -ne $null -and $createdItem.PSProvider.Name -ne "FileSystem") { Remove-Item "$DestinationPath" -Force -Recurse -ErrorAction SilentlyContinue $errorMessage = ($LocalizedData.ExpandArchiveInValidDestinationPath -f $DestinationPath) ThrowTerminatingErrorHelper "InvalidDirectoryPath" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $DestinationPath } $resolvedDestinationPath = GetResolvedPathHelper $DestinationPath $true $PSCmdlet } } $isWhatIf = $psboundparameters.ContainsKey("WhatIf") if (!$isWhatIf) { $preparingToExpandVerboseMessage = ($LocalizedData.PreparingToExpandVerboseMessage) Write-Verbose $preparingToExpandVerboseMessage $progressBarStatus = ($LocalizedData.ExpandProgressBarText -f $DestinationPath) ProgressBarHelper "Expand-Archive" $progressBarStatus 0 100 100 1 } } PROCESS { switch ($PsCmdlet.ParameterSetName) { "Path" { $resolvedSourcePaths = GetResolvedPathHelper $Path $false $PSCmdlet if ($resolvedSourcePaths.Count -gt 1) { $errorMessage = ($LocalizedData.InvalidArchiveFilePathError -f $Path, $PsCmdlet.ParameterSetName, $PsCmdlet.ParameterSetName) ThrowTerminatingErrorHelper "InvalidArchiveFilePath" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $Path } } "LiteralPath" { $resolvedSourcePaths = GetResolvedPathHelper $LiteralPath $true $PSCmdlet if ($resolvedSourcePaths.Count -gt 1) { $errorMessage = ($LocalizedData.InvalidArchiveFilePathError -f $LiteralPath, $PsCmdlet.ParameterSetName, $PsCmdlet.ParameterSetName) ThrowTerminatingErrorHelper "InvalidArchiveFilePath" $errorMessage ([System.Management.Automation.ErrorCategory]::InvalidArgument) $LiteralPath } } } ValidateArchivePathHelper $resolvedSourcePaths if ($pscmdlet.ShouldProcess($resolvedSourcePaths)) { $expandedItems = @() try { # StopProcessing is not avaliable in Script cmdlets. However the pipleline execution # is terminated when ever 'CTRL + C' is entered by user to terminate the cmdlet execution. # The finally block is executed whenever pipleline is terminated. # $isArchiveFileProcessingComplete variable is used to track if 'CTRL + C' is entered by the # user. $isArchiveFileProcessingComplete = $false # The User has not provided a destination path, hence we use '$pwd\ArchiveFileName' as the directory where the # archive file contents would be expanded. If the path '$pwd\ArchiveFileName' already exists then we use the # Windows default mechanism of appending a counter value at the end of the directory name where the contents # would be expanded. if (!$isDestinationPathProvided) { $archiveFile = New-Object System.IO.FileInfo $resolvedSourcePaths $resolvedDestinationPath = Join-Path -Path $resolvedDestinationPath -ChildPath $archiveFile.BaseName $destinationPathExists = Test-Path -LiteralPath $resolvedDestinationPath -PathType Container if (!$destinationPathExists) { New-Item -Path $resolvedDestinationPath -ItemType Directory -Confirm:$isConfirm -Verbose:$isVerbose -ErrorAction Stop | Out-Null } } ExpandArchiveHelper $resolvedSourcePaths $resolvedDestinationPath ([ref]$expandedItems) $Force $isVerbose $isConfirm $isArchiveFileProcessingComplete = $true } finally { # The $isArchiveFileProcessingComplete would be set to $false if user has typed 'CTRL + C' to # terminate the cmdlet execution or if an unhandled exception is thrown. if ($isArchiveFileProcessingComplete -eq $false) { if ($expandedItems.Count -gt 0) { # delete the expanded file/directory as the archive # file was not completly expanded. $expandedItems | ForEach-Object { Remove-Item $_ -Force -Recurse } } } } } } } function Write-LocalMessage { [CmdletBinding()] Param ( [string]$Message ) if (Test-Path function:Write-PSFMessage) { Write-PSFMessage -Level Important -Message $Message } else { Write-Host $Message } } #endregion Utility Functions try { [System.Net.ServicePointManager]::SecurityProtocol = "Tls12" Write-LocalMessage -Message "Downloading repository from '$($BaseUrl)/archive/$($Branch).zip'" Invoke-WebRequest -Uri "$($BaseUrl)/archive/$($Branch).zip" -UseBasicParsing -OutFile "$($env:TEMP)\$($ModuleName).zip" -ErrorAction Stop Write-LocalMessage -Message "Creating temporary project folder: '$($env:TEMP)\$($ModuleName)'" $null = New-Item -Path $env:TEMP -Name $ModuleName -ItemType Directory -Force -ErrorAction Stop Write-LocalMessage -Message "Extracting archive to '$($env:TEMP)\$($ModuleName)'" Expand-Archive -Path "$($env:TEMP)\$($ModuleName).zip" -DestinationPath "$($env:TEMP)\$($ModuleName)" -ErrorAction Stop $basePath = Get-ChildItem "$($env:TEMP)\$($ModuleName)\*" | Select-Object -First 1 if ($SubFolder) { $basePath = "$($basePath)\$($SubFolder)" } # Only needed for PS v5+ but doesn't hurt anyway $manifest = "$($basePath)\$($ModuleName).psd1" $manifestData = Invoke-Expression ([System.IO.File]::ReadAllText($manifest)) $moduleVersion = $manifestData.ModuleVersion Write-LocalMessage -Message "Download concluded: $($ModuleName) | Branch $($Branch) | Version $($moduleVersion)" # Determine output path $path = "$($env:ProgramFiles)\WindowsPowerShell\Modules\$($ModuleName)" if ($doUserMode) { $path = "$(Split-Path $profile.CurrentUserAllHosts)\Modules\$($ModuleName)" } if ($PSVersionTable.PSVersion.Major -ge 5) { $path += "\$moduleVersion" } if ((Test-Path $path) -and (-not $Force)) { Write-LocalMessage -Message "Module already installed, interrupting installation" return } Write-LocalMessage -Message "Creating folder: $($path)" $null = New-Item -Path $path -ItemType Directory -Force -ErrorAction Stop Write-LocalMessage -Message "Copying files to $($path)" foreach ($file in (Get-ChildItem -Path $basePath)) { Move-Item -Path $file.FullName -Destination $path -ErrorAction Stop } Write-LocalMessage -Message "Cleaning up temporary files" Remove-Item -Path "$($env:TEMP)\$($ModuleName)" -Force -Recurse Remove-Item -Path "$($env:TEMP)\$($ModuleName).zip" -Force Write-LocalMessage -Message "Installation of the module $($ModuleName), Branch $($Branch), Version $($moduleVersion) completed successfully!" } catch { Write-LocalMessage -Message "Installation of the module $($ModuleName) failed!" Write-LocalMessage -Message "Cleaning up temporary files" Remove-Item -Path "$($env:TEMP)\$($ModuleName)" -Force -Recurse Remove-Item -Path "$($env:TEMP)\$($ModuleName).zip" -Force throw } ================================================ FILE: library/d365fo.tools/d365fo.tools/Class1.cs ================================================ using System; namespace d365fo.tools { public class Class1 { } } ================================================ FILE: library/d365fo.tools/d365fo.tools/d365fo.tools.csproj ================================================  net4.5.2 ..\..\..\d365fo.tools\bin ..\..\..\d365fo.tools\bin\d365fo.tools.xml ..\..\..\d365fo.tools\bin ..\..\..\d365fo.tools\bin\d365fo.tools.xml false ================================================ FILE: library/d365fo.tools/d365fo.tools.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.27130.2010 MinimumVisualStudioVersion = 10.0.40219.1 Project("{361C84EE-64AA-4E88-94D8-2104C3670C0C}") = "d365fo.tools", "d365fo.tools\d365fo.tools.csproj", "{426BC3CD-F2B9-4B1E-95EF-C5299426A72A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {426BC3CD-F2B9-4B1E-95EF-C5299426A72A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {426BC3CD-F2B9-4B1E-95EF-C5299426A72A}.Debug|Any CPU.Build.0 = Debug|Any CPU {426BC3CD-F2B9-4B1E-95EF-C5299426A72A}.Release|Any CPU.ActiveCfg = Release|Any CPU {426BC3CD-F2B9-4B1E-95EF-C5299426A72A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3A54BDDB-A20F-4A50-9C82-E62C507D0415} EndGlobalSection EndGlobal ================================================ FILE: wiki/Azure-DevOps-Build-Configuration.md ================================================ ## **Prerequisites** You 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. ## **Configure Github Access** 1. Navigate to your Azure DevOps project 2. Click on the **"Project settings"** icon in the bottom left corner of the page [[images/image-e2513b65-f1db-4dad-a630-0e2ae6510eb9.png]] 3. Select the **"Service connections"** menu option, under the **"Pipelines"** section in the new navigation tile on the left 4. Select **"Github"** from the **"New service connection"** dropdown list [[images/image-42be014d-3dab-49a4-827b-41ba6385b913.png]] 5. Select the **"Personal access token"** option in the **"Choose authorization"** configuration 6. Fill in a desired **name** for this connection that you are creating in the **"Connection Name"** configuration 7. Fill in your token that you have created on Github in the **"Token"** configuration [[images/image-99ecf271-0fbd-4b8d-9133-970992f628b2.png]] 8. Validate that the **"Service Connection"** is created as desired and go back to your Azure DevOps project start page ## **Setup the build pipeline** 1. Select the **"Pipelines"** menu option in the navigation on the left 2. Select the **"Builds"** menu option that is revealed under the **"Pipelines"** section in the navigation on the left 3. Click the **"+ New"** iceon and select the **"New build pipeline"** from the dropdown [[images/image-424819b5-687c-4b5d-8558-9953d7912ab1.png]] Or if you never did create a build pipeline it will just show you a empty page with just one button to click [[images/image-c3d3a98c-42bd-4864-b007-8402f94a8d10.png]] 4. You have to select the **"Github"** option and validate that it selects the current **"Service Connection"** created earlier 5. Select the github repository you want to build 6. Select the default branch that the build pipeline should build when you initiate a manuel build - **"master"** is the normal default 7. Click continue when ready [[images/image-b86b0ca1-9123-4e35-9d91-3079b9a70658.png]] 8. Select the **"Empty job"** option in the very top of the page [[images/image-7a660f10-5970-4246-bb0c-053e24c67689.png]] 9. Select the new Agent job 1 and click on the + sign 10. Search for PowerShell and add 2 x PowerShell tasks [[images/image-00b1392f-9f4c-4b62-96d8-ba9e67a4e92d.png]] 11. Search for Publish Test Results and add only 1 [[images/image-7cda2c2c-0276-45de-b48a-a250bfafe0b9.png]] 12. Validate that you have **2** PowerShell tasks and **1** Publish Test Results [[images/image-a520bea2-d107-4df4-9582-534e98563aaa.png]] 13. Select the first PowerShell task, name it **"Prerequisites"** 14. Fill in **"build/vsts-prerequisites.ps1"** into the **"Script Path"** [[images/image-77dce872-0c56-440a-8103-5b1b1af5be05.png]] 15. Select the second PowerShell task, name it **"Validate"** 16. Fill in **"build/vsts-validate.ps1"** into the **"Script Path"** [[images/image-7bfbab7d-5253-4ee5-8514-b3ff67e8364b.png]] 17. Select the Publish Test Results and change the **"Test result format"** from **"JUnit"** to **"NUnit"** 18. 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"** [[images/image-a46e25f0-f4bd-446d-9942-97bcc614b4f4.png]] 19. When ready click on the **"Save & queue"** button in the top menu and select the **"Save"** option from the dropdown menu [[images/image-3c49f8ae-a868-46f7-8fa2-402e58cc341d.png]] 20. Go back to the build pipeline overview and **"Queue"** a new build 21. Accept the default values from the popup [[images/image-9482e53d-e2fc-4129-894d-c6881a23358d.png]] 22. Once the build is done and error free, you can continue the configuration of your github repository and branch protection ================================================ FILE: wiki/Branching.md ================================================ ## **Branching strategy** We 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) One 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. ## **Create a new branch from the desktop client** 1. Make sure that you have selected your local repository 2. Make sure that you have selected the master branch [[images/Branch.001.png]] 3. Click on the **master** branch icon in the top 4. Click on the **New branch** button in the drop down menu [[images/Branch.002.png]] 5. Fill in the name of the desired branch 6. Click on **Create branch** when ready - We recommend that you provide a meaningful name, without spaces [[images/Branch.003.png]] 7. Make sure that the branch was created and your local repository is switched to that [[images/Branch.004.png]] 8. Do your magic and commit stuff to your branch 9. When you are ready to create a pull request (PR), simply click on the **Publish branch** button in the top menu [[images/Branch.005.png]] 10. 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 [[images/Branch.006.png]] 11. Your default browser will now load and go to github 12. Make sure that you compared the branch against the **master** branch in the d365fo.tools repository [[images/Branch.007.png]] ================================================ FILE: wiki/Building-tools.md ================================================ 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. These 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-`. For 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. To run the scripts locally, follow the instructions below. ## **Prerequisites** * PSModuleDevelopment (PowerShell module to aid with development) * `Install-Module PSModuleDevelopment -Force -Confirm:$false` * platyPS (PowerShell module to aid with documentation for modules) * `Install-Module platyPS -Force -Confirm:$false` ## **Format Comment Based help** We 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). ## **Generate-ParameterUnitTests** We 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. ## **Update-Docs** Whenever 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. ## **Generate-FindCommandIndex** The [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). ## **Closing notes** The 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. ================================================ FILE: wiki/Call-Internal-Functions.md ================================================ # Call internal functions d365fo.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. > ⚠️ **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. ## Dot source the internal function To 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. The path to the function consists of 3 parts: 1. **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: ```powershell Split-Path $(Get-Module d365fo.tools -ListAvailable | Select-Object -First 1).Path ``` 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. 2. **The path to the function**: Within the module, the internal functions are located in the `internal\functions` folder. 3. **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`. For example, to dot source the internal function `Invoke-Process` you would use a command similar to the following: ``` . 'C:\Program Files\WindowsPowerShell\Modules\d365fo.tools\0.7.9\internal\functions\Invoke-Process.ps1' ``` ## Call the internal function Once 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: ```powershell Invoke-Process -Path 'C:\Temp\Program.exe' -Params '/help' ``` ## Dependencies Internal 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. This may require calling the function multiple times. Each time, the error messages should help you identify which dependencies are missing. For example, the `Invoke-Process` function has the following dependencies: - internal function `Invoke-TimeSignal` - internal function `Test-PathExists` - setting `$Script:TimeSignals` So to fully load the `Invoke-Process` function, you would use the following script: ```powershell . 'C:\Program Files\WindowsPowerShell\Modules\d365fo.tools\0.7.9\internal\functions\Invoke-TimeSignal.ps1' . 'C:\Program Files\WindowsPowerShell\Modules\d365fo.tools\0.7.9\internal\functions\Test-PathExists.ps1' . 'C:\Program Files\WindowsPowerShell\Modules\d365fo.tools\0.7.9\internal\functions\Invoke-Process.ps1' $Script:TimeSignals = @{} ``` > ℹ️ **Note** The dependencies of an internal function may have dependencies of their own. ================================================ FILE: wiki/Calling-the-Table-Browser-from-the-browser.md ================================================ **You want to be able to call the table browser in an easy way** ``` Invoke-D365TableBrowser -TableName SalesTable -Company "USMF" ``` *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* **Small teaser for the combination of Get-D365Table and Invoke-D365TableBrowser** ``` Get-D365Table -Name CustTable,CustTrans | Invoke-D365TableBrowser -Company USMF ``` *You want to start the table browser for **both** CustTable & CustTrans, against the USMF company* ================================================ FILE: wiki/Configuration.md ================================================ 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. # An example For 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`. We will come back to this example in the following sections to explain how the default value is determined. # The script scope You 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. For 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. # Setting the default values The 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. ## It depends You 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. For 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. ```powershell $environmentSettings = Get-D365EnvironmentSettings $environmentSettings.Aos.PackageDirectory ``` This 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. # Configurable default values You 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. The 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. Another 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. This 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. ## PSFramework A 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). You 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. However, 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. ================================================ FILE: wiki/Configure-Azure-Logic-App.md ================================================ ### **Intro** So you want to be able to notify someone when a cmdlet is done running? You read about the magical Invoke-D365LogicApp cmdlet? This will guide you through on how to configure everything inside the Azure Portal. ### **Requirements** You will need the following **before** you can start: 1. An active Azure subscription 2. An Office365 user account (Azure Active Directory) - Email license assigned ### **Prepare** Download a copy of the file [AzureLogicApp-Template.json](https://raw.githubusercontent.com/d365collaborative/d365fo.tools/master/AzureLogicApp-Template.json) and save if on your computer. ### **Implementation** 1. Visit https://portal.azure.com 2. Click **"Create a resource"** [[images/AzureLogicApp.001.png]] 3. Search for **"Template"** and select the **"Template deployment"** option from the results [[images/AzureLogicApp.002.png]] 4. Click "Create" [[images/AzureLogicApp.003.png]] 5. Click **"Build your own template in the editor"** [[images/AzureLogicApp.004.png]] 6. Click **"Load file"** [[images/AzureLogicApp.005.png]] 7. Locate the **"AzureLogicApp-Template.json"* file that you downloaded earlier. [[images/AzureLogicApp.006.png]] 8. 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. [[images/AzureLogicApp.007.png]] 9. Fill in all the details that are necessary, click the **"I agree to the terms and conditions stated above"** checkbox and click on **"Purchase"** [[images/AzureLogicApp.008.png]] 10. Wait for the deployment to complete. Click on the notification icon in the top right corner. [[images/AzureLogicApp.009.png]] 11. Click on **"Resource groups"** and search for the resource group you filled in during deployment. Click the resource group to continue. [[images/AzureLogicApp.011.png]] 12. Click on **"NotifyWhenDone"** (Logic App) - remember that you could have changed the name during deployment. [[images/AzureLogicApp.012.png]] 13. Click **"Edit"** [[images/AzureLogicApp.013.png]] 14. Click on the **"Connections"** bar with the **Outlook** icon and the yellow/orange exclamation mark. Click on **"Invalid Connection"**. [[images/AzureLogicApp.014.png]] 15. Select an account of yours that is an AAD and have an email license. [[images/AzureLogicApp.015.png]] 16. Click on the connection that has a blue checkmark to the left. [[images/AzureLogicApp.016.png]] 17. Validate that things look like they should. [[images/AzureLogicApp.017.png]] 18. Save the Logic App. 19. Click **"Edit"** once more. 20. Click **"When a Http Request is received"** and click on the copy to clipboard button next to the URL. [[images/AzureLogicApp.018.png]] ================================================ FILE: wiki/Deprecation-guidelines.md ================================================ 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. To track the deprecation and removal of a cmdlet, an issue should be created that should be labeled [deprecation](../labels/deprecation). ================================================ FILE: wiki/Do-And-Do-Not.md ================================================ # Writing Documentation: * [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) * [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) # Writing Code: * [Prefer dot notation over `Select -ExpandProperty`.](https://trello.com/c/p9c6clqP/59-using-get-childitem-fullname-or-get-childitem-select-expandproperty-fullname) * eg. `(Get-ChildItem).FullName` * [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) * [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) * eg. `$null = $result = Command-WhichProducedOutputWhenAssigned` * [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) * [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) * [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): * eg. Constructing a pscustomobject from a hash table, also useful for cheap object creation: ``` [pscustomobject]@{ ServerName = $servername IsEnabled = $true } ``` * [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) * [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) * [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) * [Casing follows PowerShell community recommendations](https://trello.com/c/MxprMJhU/5-casing-of-if-else-continue-return-begin-process-end): * Lower: * Language keyword (try, catch, foreach) * Process block keyword (begin, process, end) * Pascal: * Comment help keywords (.Example, .Synopsis) * Package or modules * Class * Exception * Global variables * Camel Case: * Local variables ($localArgument) * There may be rare cases in which features do not work without required casing, in those cases ignore these recommendations. * [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) * The defacto naming convention for any command is ApprovedVerb-D365* * [Use one space after a bracket.](https://trello.com/c/Lb6rUOD4/37-how-should-spaces-must-come-after-brackets-where-object-whatever-eq-whatever) * [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) * [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) * [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) **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. ================================================ FILE: wiki/Exception-handling.md ================================================ 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. While 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. If 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. # How to stop execution of the cmdlets in case of a warning? The 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: ``` $WarningPreference="Stop" ``` This will change the behavior of all PowerShell commands that are executed after this variable has been set for the remainder of the PowerShell session. If you want to restore the default behavior, run the following command or start a new PowerShell session: ``` $WarningPreference="Continue" ``` To 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). ``` Get-Help About_Preference_Variables ``` # How to throw exceptions? While 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. To cover those situations, the d365fo.tools provide a cmdlet to activate exceptions: `Enable-D365Exception` By 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. However, note that only cmdlets with the `-EnableException` parameter support this type of exception handling. To disable throwing exceptions, call the `Disable-D365Exception` cmdlet. ## What does the -EnableException parameter do? You 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. You 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. # Why are exceptions handled like this? The 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. This 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. For 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. ## Can this be changed? We 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. ================================================ FILE: wiki/Fix-AzureStorageConfig.md ================================================ Got hit by our breaking change with the names of the parameters for the Add-AzureStorageConfig, Get-AzureStorageConfig ``` $configs = Get-D365AzureStorageConfig $configs | ForEach-Object {Add-D365AzureStorageConfig -Name $_.Name -AccountId $_.AccountId -SAS $_.SAS -Container $_.Blobname -Force} ``` ================================================ FILE: wiki/Getting-Started-with-GitHub.md ================================================ 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. ## Understanding the process/tools [How to Github: Fork, Branch, Track, Squash and Pull Request](https://gun.io/blog/how-to-github-fork-branch-and-pull-request/) [Contributing to Projects with GitHub Desktop](https://help.github.com/desktop/guides/contributing/) ## Actually doing it [Learning Git Branching](http://learngitbranching.js.org/) - Online lab of sorts for trying out and learning Git command line. ## Creating your first pull request If 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). ## Really cool tutorial site! [git-scm](https://git-scm.com/) **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. ================================================ FILE: wiki/Home.md ================================================ Welcome to the d365fo.tools wiki! Here 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. ================================================ FILE: wiki/How-To-Authenticate-With-LCS-API.md ================================================ # **LCS API Authentication** The LCS (Lifecycle Services) API authentication will enable you to use the functionality provided by the LCS API. This 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. ## **Prerequisites** * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session * User account without MFA enabled * Should already be able to log into LCS and be part of the project * Registered Application in the Azure AD * Needs to have the "Dynamics Lifecycle services" permission assigned and granted/consented * LCS Project Id Please 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. Please 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. To 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/) ## **Configure LCS API access details** For 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. The following script will: 1. Test that your username, password and registered application is working 2. Store the authentication token and registered application along with the LCS project id ```powershell # We will start by testing that we can obtain a valid OAuth token, to make sure our details are correct Get-D365LcsApiToken -ClientId "e70cac82-6a7c-4f9e-a8b9-e707b961e986" -Username "Lcs-Automation@contoso.com" -Password "fT1DHcLdeTWC9aumugHr" -LcsApiUri "https://lcsapi.lcs.dynamics.com" # Now we are going to save the details, the refresh token, the registered application and the project id Get-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" ``` [[images/howtos/Authenticate-LCS-API.gif]] So 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. ================================================ FILE: wiki/How-To-Compile-Model.md ================================================ # **Compile module** This how-to will guide you on how to compile a module without using Visual Studio. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session Please 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. Please 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. ## **List all modules / models** Listing all installed modules / models can help you while troubleshooting your environment. Type the following command: ```PowerShell Get-D365Module ``` [[images/howtos/Get-Modules.gif]] ## **Search for modules / models** To limit the output of modules in the console, you can utilize the search functionality in the `Get-D365Module` cmdlet. Type the following command: ```PowerShell Get-D365Module -Name *Project* ``` [[images/howtos/Get-Modules-Search.gif]] ## **Compile module / model** We need to know the name of the module / model that we want to compile, and provide that as a parameter. Type the following command: ```PowerShell Invoke-D365ModuleFullCompile -Module Project ``` [[images/howtos/Compile-Single-Module.gif]] ## **Compile multiple modules / models** We 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: ```PowerShell Get-D365Module -Name *Project* | Invoke-D365ModuleFullCompile ``` [[images/howtos/Compile-Modules.gif]] You can also use utilize `-InDependencyOrder` parameter of `Get-D365Module` to get and compile modules in the right order. One module might depend on other modules and this allows you to compile dependencies first. ## **Closing comments** In 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. ================================================ FILE: wiki/How-To-Download-Latest-Bacpac-From-Lcs.md ================================================  # **Download latest bacpac from LCS via AzCopy** This 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. - **TOC** * [**Prerequisites**](#--prerequisites--) * [**Configure Azure Storage Account**](#--configure-azure-storage-account--) * [**Configure LCS API access details**](#--configure-lcs-api-access-details--) * [**Download the latest bacpac file from LCS via AzCopy**](#--download-the-lastest-bacpac-file-from-lcs-via-azcopy--) * [**Closing comments**](#--closing-comments--) ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session * AzCopy installed * https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Install-AzCopy * Azure Storage account * Blob Container * SAS token to Blob Container * To make the initial testing easier, it should be full permission * User account without MFA enabled * Should already be able to log into LCS and be part of the project * Registered Application in the Azure AD * Needs to have the "Dynamics Lifecycle services" permission assigned and granted/consented * LCS Project Id Please 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. Please 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. To 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/) ## **Configure Azure Storage Account** To 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. The following script will: 1. Add the connection details and store them 2. Show the newly added details 3. Configure the added details as the active configuration 1. This will be persisted for the next time you load the module 4. List all files/blobs that are already inside your container ```powershell #We'll start with adding and storing the connection details for the Azure Storage Account Add-D365AzureStorageConfig -Name "TestAccount" -AccountId "motz" -Container "demo" -SAS "?sv=2018-03-28&si=full&sr=c&sig=N3vCp95UUhlpdBxL5QZCjOrp0o30Yxdj17PJ70nxMc4%3D" #Let's see the details we just saved Get-D365AzureStorageConfig #Now we are going to set the config as the active Set-D365ActiveAzureStorageConfig -Name "TestAccount" #Do we have anything in it already? Get-D365AzureStorageFile ``` [[images/howtos/01.00-LCS-API-Add-D365AzureStorageConfig.gif]] So 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. ## **Authenticate with LCS and retrieve database backup information from LCS** The 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. To 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). The following script will: 1. Authenticate with the LCS API and store the refresh token and registered application along with the LCS project id 2. List all available bacpacs and backups from the LCS Asset Library 3. List the latest bacpac / backup from the LCS Asset Library ```powershell # Authenticate with the LCS API and save the details, the refresh token, the registered application and the project id Get-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" # Retrieve a list of available backups Get-D365LcsDatabaseBackups # Retrieve only the latest backup Get-D365LcsDatabaseBackups -Latest ``` [[images/howtos/Authenticate-LCS-Get-Backups.gif]] So 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. ## **Download the latest bacpac file from LCS via AzCopy** AzCopy 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. Whenever you list backups from the LCS API, the output will always contain a complete url for the specific file, containing a SAS token. Because 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. You 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. The following script will: 1. Generate a complete Url/Uri, containing a SAS token 2. Start the transfer of the latest bacpac file and into our own 3. List all available bacpacs and backups from the LCS Asset Library 4. List the latest bacpac / backup from the LCS Asset Library ```powershell # With the Azure Storage Account persisted, we can now generate a complete Url/Uri Get-D365AzureStorageUrl # Let us connect the dots and utilize the Azure Storage Account to speed up the download # Generate complete Url/Uri $TempDestination = Get-D365AzureStorageUrl -OutputAsHashtable # Transfer the latest bacpac file from LCS to our own Azure Storage Account $BlobParms = Get-D365LcsDatabaseBackups -Latest | Invoke-D365AzCopyTransfer @TempDestination -FileName "Latest.bacpac" # Let us see if we really got the bacpac file transferred into our own Azure Storage Account Get-D365AzureStorageFile # Transfer the bacpac file from our Azure Storage Account and onto our machine. $BlobParms | Invoke-D365AzCopyTransfer -DestinationUri "C:\Temp" -DeleteOnTransferComplete # Let us see if we removed the temporary file from our Azure Storage Account Get-D365AzureStorageFile ``` [[images/howtos/01.02-LCS-API-Get-D365LcsDatabaseBackups.gif]] So now you will have the latest bacpac file downloaded onto your own machine, while removing the temporary file from the Azure Storage Account. ## **Closing comments** In 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. ================================================ FILE: wiki/How-To-Enable-Users-In-Db.md ================================================ # **Enable users in the D365FO environment** This 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. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session Please 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. Please 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. ## **Enabling the users in the database** We 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: ``` Get-D365User -ExcludeSystemUsers | Enable-D365User ``` [[images/howtos/Enable-Users.gif]] ## **Closing comments** In 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. ================================================ FILE: wiki/How-To-Export-Bacpac-From-Tier1.md ================================================ # **Export a bacpac file from a Tier1 environment** This how-to will guide you while you will be exporting a bacpac file from a Tier1 environment. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session Please 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. Please 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. ## **Stop all D365FO services** We 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: ``` Stop-D365Environment -All ``` [[images/howtos/Stop-Services.gif]] ## **Export bacpac file** We 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: ``` New-D365Bacpac -ExportModeTier1 -ShowOriginalProgress ``` [[images/howtos/Export-Bacpac.gif]] The command will run for quite some time, but it will eventually exit and output the file location of the newly created bacpac file. ## **Closing comments** In 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. ================================================ FILE: wiki/How-To-Import-Bacpac-Into-Tier1.md ================================================ # **Import a bacpac file into a Tier1 environment** This how-to will guide you while you will be importing a bacpac file into a Tier1 environment. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session * Valid bacpac file Please 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. Please 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. ## **Import bacpac file into the SQL Server** We want to import the bacpac file into the SQL Server, and we want to do that into a new database. Type the following command: ``` Import-D365Bacpac -BacpacFile "C:\Temp\d365fo.tools\AxDB.bacpac" -ImportModeTier1 -NewDatabaseName GOLDEN ``` [[images/howtos/Import-Bacpac.gif]] ### Troubleshooting If 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. ``` Invoke-D365InstallSqlPackage ``` ## **Stop all D365FO services** We 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: ``` Stop-D365Environment -All ``` [[images/howtos/Stop-Services.gif]] ## **Switch databases** With the newly created GOLDEN database, we will be switching it in as the D365FO database. Type the following command: ``` Switch-D365ActiveDatabase -SourceDatabaseName GOLDEN ``` [[images/howtos/Switch-Database.gif]] ## **Synchronize the D365FO databases** With 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: ``` Invoke-D365DBSync -ShowOriginalProgress ``` [[images/howtos/Invoke-DBSync.gif]] ## **Start all D365FO services** With 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: ``` Start-D365Environment -All ``` [[/images/howtos/Start-Services.gif]] ## **Closing comments** In 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. ================================================ FILE: wiki/How-To-Import-External-User-Into-Db.md ================================================ # **Import external users into the D365FO environment** This how-to will guide you on how to import external users into your D365 environment. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session Please 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. Please 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. ## **Import an external user into the database** We 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: **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. ``` Import-D365ExternalUser -Id test -Name test -Email test@e-s.dk ``` [[images/howtos/Import-ExternalUser.gif]] ## **Closing comments** In this how to we showed you how to import an external user into the D365FO database. ================================================ FILE: wiki/How-To-Import-User-Into-Db.md ================================================ # **Import users into the D365FO environment** This how-to will guide you on how to import users into your D365 environment. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session * Valid Azure AD user account capable of signing into Office365 Please 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. Please 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. ## **Import an user into the database** We 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: **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. ``` Import-D365AadUser -Users test@e-s.dk ``` [[images/howtos/Import-AadUser.gif]] ## **Closing comments** In this how to we showed you how to import an Azure AD user into the D365FO database. ================================================ FILE: wiki/How-To-Install-AzCopy.md ================================================ # **Install AzCopy** This how-to will guide you on how to install the latest available AzCopy onto your machine. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session Please 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. Please 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. ## **Install latest AzCopy** Installation 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: ``` Invoke-D365InstallAzCopy ``` [[images/howtos/Invoke-InstallAzCopy.gif]] ## **Closing comments** In 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. ================================================ FILE: wiki/How-To-Install-NuGet.md ================================================ # **Install NuGet** This how-to will guide you on how to install the latest available nuget.exe onto your machine. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session Please 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. Please 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. ## **Install latest nuget.exe** Installation 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: ``` Invoke-D365InstallNuget ``` [[images/howtos/Invoke-D365InstallNuget.gif]] ## **Closing comments** In 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. ================================================ FILE: wiki/How-To-Install-SqlPackage.md ================================================ # **Install SqlPackage** This how-to will guide you on how to install the latest available SqlPackage onto your machine. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session Please 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. Please 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. ## **Install latest SqlPackage** Installation 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: ``` Invoke-D365InstallSqlPackage ``` [[images/howtos/Invoke-InstallSqlPackage.gif]] ## **Closing comments** In 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. ================================================ FILE: wiki/How-To-List-Models.md ================================================ # **List modules / models** This how-to will guide you on how to list and search for modules / models. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session Please 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. Please 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. ## **List all modules / models** Listing all installed modules / models can help you while troubleshooting your environment. Type the following command: ```PowerShell Get-D365Module ``` [[images/howtos/Get-Modules.gif]] ## **List all modules / models** To limit the output of modules in the console, you can utilize the search functionality in the `Get-D365Module` cmdlet. Type the following command: ```PowerShell Get-D365Module -Name *Project* ``` [[images/howtos/Get-Modules-Search.gif]] ## **Closing comments** In 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. ================================================ FILE: wiki/How-To-Provision-Environment-Tier1.md ================================================ # **Provision D365FO environment to new Azure AD tenant** This how-to will guide you on how to provision Tier1 environment to be connected to new Azure AD tenant. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session * Valid Azure AD user account that should be assigned as the D365FO administrator Please 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. Please 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. ## **Provision user to the new D365FO administrator in the database** For 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: Please 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. ``` Set-D365Admin -AdminSignInName test@e-s.dk ``` [[images/howtos/Provision-Admin.gif]] ### **Troubleshooting** You 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. ## **Closing comments** In 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. If 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. ================================================ FILE: wiki/How-To-Register-NuGet-Source.md ================================================ # **Register NuGet source** This 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. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session * NuGet installed (via Invoke-D365InstallNuget) * Valid Personal Access Token (PAT) obtained from the Azure DevOps project your Azure DevOps feed is hosted * Correctly formatted feed url for the Azure DevOps feed your want to work against Please 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. Please 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. Please 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). A correctly formatted feed url is like: https://pkgs.dev.azure.com/OrganizationName/ProjectName/_packaging/FeedName/NuGet/v3/index.json Where you need to fill in the **OrganizationName** - **ProjectName** - **FeedName** details. E.g. https://pkgs.dev.azure.com/Contoso/DynamicsFnO/_packaging/D365Packages/nuget/v3/index.json ## **Register NuGet source** Either 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: ```powershell cd "C:\Temp\d365fo.tools\NuGet" ``` Now 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: ```powershell .\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" ``` ## **Closing comments** In 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. ================================================ FILE: wiki/How-To-Start-Stop-List-D365FO-Services.md ================================================ # **Start, Stop and List services** This how to will guide you on how to manage the different D365FO services on a machine. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session Please 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. Please 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. ## **List all available D365FO services** If you want to see the entire list of D365FO services and/or see their current running state, type the following command: ``` Get-D365Environment -All ``` ### **Output while services are running** [[images/howtos/Get-Services-While-Running.gif]] ### **Output while services are stopped** [[images/howtos/Get-Services-While-Stopped.gif]] ## **Stop all D365FO services** If you want to stop all services on the machine, maybe you want to install an update or import a model, type the following command: ``` Stop-D365Environment -All ``` [[images/howtos/Stop-Services.gif]] ## **Start all D365FO services** If you want to start all services on the machine, type the following command: ``` Start-D365Environment -All ``` [[images/howtos/Start-Services.gif]] ## **Restart all D365FO services** If you want to restart all services on the machine, maybe because you are having some issues with caching, type the following command: ``` Restart-D365Environment -All ``` [[images/howtos/Restart-Services.gif]] ## **Closing comments** In this how to we showed you how to use the d365fo.tools module to manage the different D365FO specific services. ================================================ FILE: wiki/How-To-Transfer-Via-AzCopy.md ================================================ # **Speed up LCS download via AzCopy** This 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. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session * Storage account (Full url is needed) * Blob Container * SAS token to Blob Container, should be a full permission while testing Please 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. Please 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. ## **Start download from LCS via the browser** We need to get a hold of a complete source url from LCS, and thankfully it is super easy. Please see below guide: [[images/howtos/LCS-Download-v2.gif]] The 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. The source URL/URI in our example is: "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" ## **Transfer the file into your own Storage Account** You 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. In out example these are the following details: **Storage Account URL/URI**: "https://motz.blob.core.windows.net/" **Container Name**: "azcopytest" **SAS Token**: "?sv=2018-03-28&si=full&sr=c&sig=PH5douKkqJJrbl8CoQjizopFCtgnL50aLUJzY0k1Xqc%3D" **Desired Filename**: "FinandOps10.0.5.part16.rar" The combined destination URL/URI ends up being: "https://motz.blob.core.windows.net/azcopytest/FinandOps10.0.5.part16.rar?sv=2018-03-28&si=full&sr=c&sig=PH5douKkqJJrbl8CoQjizopFCtgnL50aLUJzY0k1Xqc%3D" With 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: ``` Invoke-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 ``` [[images/howtos/Transfer-From-Lcs-To-Own-Storage.gif]] Here you can see that the file is actually stored in the container under our Storage Account. [[images/howtos/Show-File-In-Blob-Container.gif]] ## **Transfer the file from your own Storage Account to your machine** When 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: ``` Invoke-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 ``` [[images/howtos/Transfer-From-Own-Storage-To-Local.gif]] Here you can see that the file is actually stored our machine. [[images/howtos/Show-File-Local.png]] ## **Closing comments** In 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. ================================================ FILE: wiki/How-To-Update-Users-In-Db.md ================================================ # **Update users in the D365FO environment** This 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. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed * d365fo.tools module loaded into a PowerShell session Please 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. Please 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. ## **Update the users in the database** We 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: ``` Get-D365User -ExcludeSystemUsers | Update-D365User ``` [[images/howtos/Update-Users.gif]] ## **Closing comments** In 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. ================================================ FILE: wiki/How-To-Write-Wiki-Pages.md ================================================ # Create gifs To create gif files from a PowerShell cmdlet execution, you can use the following two programs to - record the execution: [ShareX](https://getsharex.com/) - fine tune the gif: [ScreenToGif](https://www.screentogif.com/) After 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. You can open one of the existing gifs in ScreenToGif to see what wait timeout is configured. ================================================ FILE: wiki/Implementing-the-messaging-system.md ================================================ 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'. The rest being ... - Logging the message - Deciding whether it should be written to the console screen (host/information) - Deciding whether it should be written to verbose only - Deciding whether it should be written to debug - Deciding whether it should be written as a warning It will also automatically add a timestamp and the name of the function calling it to the message. Here's a simple example on how to use it: ```PowerShell Write-PSFMessage -Level Verbose -Message "I'm an example message and will probably - but not necessarily - written to the verbose stream" ``` # The Levels of power There 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. By default, the first three levels are written to screen: * Critical / 1 * Important / Output / 2 * Significant / 3 By default, the second set of three levels are written to verbose only: * VeryVerbose / 4 * Verbose / 5 * SomewhatVerbose / 6 All messages get sent to debug by default, but three more levels exist that are debug only: * System / 7 * Debug / 8 * InternalComment / 9 Finally, there's the warning level: * Warning / 666 In all cases, both the text as well as the numerical value can be used at your own discretion. # When to use? Basically, 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.) As a general guideline though: ## When to give warning Whenever 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: ```PowerShell Write-Message -Level Warning -Message "Failed to access XYZ. Continuing but will lack some information" ``` As shown in the example, this is usually used when a function fails to access supplementary data. This 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. ## When to directly contact the user The 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. Things that should be communicated to the user: - Deprecation warnings - Loading additional resources that one would not expect to need when running the function (e.g.: Importing another module) - Sanity checks. Keeping users from committing folly is high on our todo list. - Information that may induce a human user to interrupt execution ## This ain't no chat engine The 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. General usage and associated Level: - Setup actions taken in the begin block: Verbose/5 - Starting to process an input item (Such as an object received from pipeline): VeryVerbose/4 - Individual processing phases: Verbose/5 - Actions that are part of a processing phase: SomewhatVerbose/6 Example: _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!_ ```PowerShell function Get-Test { [CmdletBinding()] Param ( [Parameter(ValueFromPipeline = $true)] $InputObject ) Begin { Write-Message -Level Verbose -Message "Connecting to Server" $smo = Connect-SqlServer } Process { foreach ($Item in $InputObject) { Write-Message -Level VeryVerbose -Message "Processing $Item" #region 1) Do Stuff Write-Message -Level Verbose -Message "Doing stuff with $Item" Do-Stuff $Item #endregion 1) Do Stuff #region 2) Do more stuff Write-Message -Level Verbose -Message "Doing more stuff with $Item" Write-Message -Level SomewhatVerbose -Message "Converting stuff" Convert-Stuff $item Write-Message -Level SomewhatVerbose -Message "Waiting for stuff" Wait-ForStuff $item Write-Message -Level SomewhatVerbose -Message "Removing stuff" Remove-Stuff $item #endregion 2) Do more stuff #region 3) Finish doing stuff Write-Message -Level Verbose -Message "Finishing doing stuff with $Item" Close-Stuff $item #endregion 3) Finish doing stuff } } End { Write-Message -Level Verbose -Message "Disconnecting from Server" $smo.Disconnect() } } ``` ## Debugging messages Finally, 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. Also 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. # Minimum usage The minimum required in a d365fo.tools function is: - Warnings as described in the warnings section - VeryVerbose and Verbose messages, as shown in the section on verbosity **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. ================================================ FILE: wiki/Load-individual-files-or-dot-source-the-files.md ================================================ 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. It has some drawbacks in relation to troubleshooting and tinkering with the module after you have installed it from www.powershellgallery.com If 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. ### **Note** **Exit** you current powershell console and start a entirely fresh powershell console, **without** loading the module. ``` Set-PSFConfig d365fo.tools.Import.IndividualFiles -Value $true Set-PSFConfig d365fo.tools.Import.DoDotSource -Value $true Import-Module d365fo.tools -Force -Passthru ``` ================================================ FILE: wiki/Old-readme-examples.md ================================================ ## **Provided as-is** This page is a direct copy & paste of the old repository readme page. We have stored all the examples here as a courtesy. Some 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. If 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. ### **Install without administrator privileges** ``` Install-Module -Name d365fo.tools -Scope CurrentUser ``` ### **List all available commands / functions** ``` Get-Command -Module d365fo.tools ``` ### **Update the module** ``` Update-Module -name d365fo.tools ``` ### **Get product build numbers** ``` Get-D365ProductInformation ``` *Will list all build numbers available, application and platform* ### **Rename a local VM (onebox) to be accessible on a custom URL / URI.** ``` Get-D365InstanceName ``` *Displays the current instance registered on the machine. Run on a machine with the D365 AOS installed on to get an result* ``` Rename-D365Instance -NewName 'Demo1' ``` *Now the machine (iis) will only respond to request for https://demo1.cloud.onebox.dynamics.com* ### **Change the start page of the browser to another URL / URI** ``` Set-D365StartPage -Name 'Demo1' ``` *Now when starting the browser you will start visit https://demo1.cloud.onebox.dynamics.com* ## **Working with users** ### **Provision a new admin for a given instance** ``` Set-D365Admin "admin@contoso.com" ``` *Please remember that the username / e-mail has to be a valid Azure Active Directory* ### **Import a list of users into the environment** ``` Import-D365AadUser -Users "Claire@contoso.com","Allen@contoso.com" ``` *Imports Claire and Allen into the environment* ### **Import a list of users into the environment based on Azure AD Group** ``` Import-D365AadUser -AadGroupName "D365 Users" -ForceExactAadGroupName ``` *Imports all users included into "D365 Users" Azure AD Group into the environnement* *The ForceExactAadGroupName parameter force command to find the AD group by searching for the exact name* ### **Update users in an environment after database migration / restore or re-provisioning** ``` Update-D365User -Email "claire@contoso.com" ``` *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* ### **Update users in an environment after database migration / restore or re-provisioning - advanced** ``` Update-D365User -Email "*contoso.com" ``` *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* ### **Enable users in an environment after database refresh from Prod to Sandbox** ``` Enable-D365User -Email "claire@contoso.com" ``` *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* ### **Enable users in an environment after database refresh from Prod to Sandbox - advanced** ``` Enable-D365User -Email "*@contoso.com" ``` *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* ### **Import an user as sysadmin** ``` Set-D365SysAdmin ``` *This will import the local administrator on the machine into the registered SQL Server.* **Notes:*You will have to run from an elevated console if you want to avoid supplying username and password*** ### **Delete an user** ``` Remove-D365User -Email "Claire@contoso.com" ``` *This will remove the user with the email address "Claire@contoso.com" and all the configured security roles.* ## **Work with bacpac files** ### **Generate a bacpac file from a Tier1 environment to be ready for a Tier2 environment** ``` New-D365Bacpac -ExportModeTier1 -DatabaseServer localhost -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" -BackupDirectory c:\Temp\backup\ -NewDatabaseName Testing1 -BacpacFile C:\Temp\Bacpac\Testing1.bacpac ``` *This will backup the db database from the localhost server.* *It will restore the backup back into the localhost server with a new name "Testing1".* *It will clean up the Testing1 database for objects that cannot exist in Azure DB.* *It will start the sqlpackage.exe file and export a valid bacpac file.* *It will delete the Testing1 database on the localhost server.* ### **Generate a bacpac file from a Tier2 environment. As an export / backup file only** ``` New-D365Bacpac -ExportModeTier2 -DatabaseServer dbserver1.database.windows.net -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" -BacpacFile C:\Temp\Bacpac\Testing1.bacpac -ExportOnly ``` *This will export an bacpac file directly from the db database from the Azure db instance at dbserver1.database.windows.net.* ### **Generate a bacpac file from a Tier2 environment to be ready for a Tier1 environment** ``` New-D365Bacpac -ExportModeTier2 -DatabaseServer dbserver1.database.windows.net -DatabaseName AxDB -SqlUser User123 -SqlPwd "Password123" -NewDatabaseName Testing1 -BacpacFile C:\Temp\Bacpac\Testing1.bacpac ``` *This will create a copy of the db database in the Azure db instance at dbserver1.database.windows.net.* *It will clean up the Testing1 database for objects that cannot exist in SQL Server.* *It will start the sqlpackage.exe file and export a valid bacpac file.* *It will delete the Testing1 database in the Azure db instance at dbserver1.database.windows.net.* ### **Import bacpac file into Tier1** ``` Import-D365Bacpac -ImportModeTier1 -BacpacFile "C:\temp\uat.bacpac" -NewDatabaseName "ImportedDatabase" ``` *This will import into the registered sql server and create a new **"ImportedDatabase"** database.* *It will import the bacpac file **"C:\temp\uat.bacpac"** and prepare the database for D365.* ### **List all the database connection details for an environment** ``` Get-D365DatabaseAccess ``` *This will show database connection details that D365FO is configured with* ### **Decrypt and store a copy of the web.config file from the AOS** ``` Get-D365DecryptedConfigFile -DropPath 'C:\Temp' ``` *This will store a decrypted web.config file at c:\temp* ## **Working with Windows license / activation** ### **Get current activation status** ``` Get-D365WindowsActivationStatus ``` *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* ### **Re-arm the machine and restart it when done** ``` Invoke-D365ReArmWindows -Restart ``` *This will try to rearm the Windows license and will only work if you have retries left. Will restart afterwards.* ### **Sync the database like Visual Studio** ``` Invoke-D365DBSync ``` *This utilizes the same mechanism as Visual Studio just in PowerShell and runs the entire synchronization process.* ## **Handling D365 environment** ### **Get current state of D365FO services of machine** ``` Get-D365Environment ``` *Will list the status of all D365 services on the local machine* ### **Get current state of D365 services on "TEST-SB-AOS-1" and "TEST-SB-AOS-2"** ``` Get-D365Environment -ComputerName "TEST-SB-AOS1","TEST-SB-AOS2" -All ``` *Will list the status of all D365 services on the specified machines* ### **Stop all D365FO services on machine** ``` Stop-D365Environment ``` *Will stop all D365 services on the local machine. Will report current status for all services* ### **Stop all D365FO services on "TEST-SB-AOS-1" and "TEST-SB-AOS-2"** ``` Stop-D365Environment -ComputerName "TEST-SB-AOS1","TEST-SB-AOS2" -All ``` *Will stop all D365 services on the the specified machines. Will report current status for all services* ### **Start all D365FO services on machine** ``` Start-D365Environment ``` *Will start all D365 services on the local machine. Will report current status for all services* ### **Start all D365FO services on "TEST-SB-AOS-1" and "TEST-SB-AOS-2"** ``` Start-D365Environment -ComputerName "TEST-SB-AOS1","TEST-SB-AOS2" -All ``` *Will start all D365 services on the the specified machines. Will report current status for all services* ### **Get all exposed D365FO services** ``` Get-ExposedService -ClientId "YouClientIdFromAppRegistration" -ClientSecret "TheSecretFromTheAppRegistration" ``` Will return a json containing the exposed services of the D365FO. It is possible to provide - Authority [Defaulted to current instance identity provider] - D365FO [Defaulted to current D365FO Enviroment] ### **Create self-signed certificates and configure AOS WIF trusted authorities** ``` Initialize-D365TestAutomationCertificate ``` Creates a new self signed certificate for automated testing and reconfigures the AOS Windows Identity Foundation configuration to trust the certificate ## **Fix misc issues** ### **Get Offline Authentication Administrator Email** ``` Get-D365OfflineAuthenticationAdminEmail ``` *Will display the current registered account as Offline Authentication Administrator* ### **Set Offline Authentication Administrator Email** ``` Set-D365OfflineAuthenticationAdminEmail -Email "admin@contoso.com" ``` *Will update the Offline Authentication Administrator registration to "admin@contoso.com"* ### **Get ClickOnce configuration** ``` Get-D365ClickOnceTrustPrompt ``` *This will get the current ClickOnce trust prompt configuration on the machine* ### **Set ClickOnce configuration** ``` Set-D365ClickOnceTrustPrompt ``` *This will set the necessary ClickOnce trust prompt configuration on the machine* ### **Get the Deployable Packages cleanup retention ** ``` Get-D365SDPCleanUp ``` *This will display the current retention that is configured on the server. If the result is empty it means that this has never been configured.* ### **Set the Deployable Packages cleanup retention ** ``` Set-D365SDPCleanUp -NumberOfDays 10 ``` *This either create or update the cleanup retention in the registry and set it to 10 days.* ***Notes: Please note that the Set-D365SDPCleanUp requires elevated permissions to work.*** ## **Work with packages, label files, language and labels** ### **Get all installed packages on the machine** ``` Get-D365InstalledPackage ``` *Gets all installed packages on the system/machine* ### **Get installed package by searching for a name** ``` Get-D365InstalledPackage -Name "ApplicationSuite" ``` *Gets the "ApplicationSuite" package* ### **Get all label files for a installed package** ``` Get-D365InstalledPackage -Name "ApplicationSuite" | Get-D365PackageLabelFile -Language "en-US" ``` *Gets all the "en-US" resource / label files from the ApplicationSuite package* ### **Get label files by searching for a name** ``` Get-D365InstalledPackage -Name "ApplicationSuite" | Get-D365PackageLabelFile -Language "en-US" -Name "PRO" ``` *Gets the PRO resource / label file from the "ApplicationSuite" package with the language "EN-US"* ### **Get all label names and values from a label file** ``` Get-D365InstalledPackage -Name "ApplicationSuite" | Get-D365PackageLabelFile -Language "en-US" -Name "PRO" | Get-D365Label ``` *Gets all label details from the PRO resource / label file from the "ApplicationSuite" package with the language "EN-US"* ### **Get label details by searching for a name** ``` Get-D365InstalledPackage -Name "ApplicationSuite" | Get-D365PackageLabelFile -Language "*" -Name "PRO" | Get-D365Label -Name "@PRO505" ``` *Gets the "@PRO505" label details from the "PRO" resource / label file from the "ApplicationSuite" package, **across all languages*** ### **Get label details by search for a value** ``` Get-D365InstalledPackage -Name "ApplicationSuite" | Get-D365PackageLabelFile -Language "en-US" | Get-D365Label -Value "*qty*" -IncludePath ``` *Gets all "en-US" labels where the value contains "*qty*" from the "ApplicationSuite" package, **across all resource / label files*** ### **Execute SysFlushAod class** ``` Invoke-D365SysFlushAodCache ``` *Will execute a web call to the SysRunnerClass with the name SysFlushAod class and have the class executed* ### **Call the Table Browser** ``` Invoke-D365TableBrowser -TableName SalesTable -Company "USMF" ``` *Will call the Table Browser in the web browser and display all data from the SalesTable within the "USMF" company* ### **Execute runnable class** ``` Invoke-D365SysRunnerClass -ClassName SysDBInformation -Company USMF ``` *Will execute a web call to the SysRunnerClass with the SysDBInformation as the parameter and have the class executed against the USMF company* ## **Work with tables, fields and ids** ### **Look up table details by id** ``` Get-D365Table -Id 10347 ``` *Will get the details for the table with the id 10347* ### **Look up table details by searching for a name** ``` Get-D365Table -Name CustTable ``` *Will get the details for the CustTable* ### **Look up field details by TableId** ``` Get-D365TableField -TableId 10347 ``` *Will get all fields and details for these fields for the table with id 10347* ### **Look up field details by searching for a table name** ``` Get-D365TableField -TableName CustTable ``` *Will get all fields and details for these fields for the table CustTable* ### **Get field details by TableId and FieldId** ``` Get-D365TableField -TableId 10347 -FieldId 175 ``` *Will get the details for the field with id 175 that belongs to the table with id 10347* ### **Get field details by TableId and by searching for a field name* ``` Get-D365TableField -TableId 10347 -Name "VAT*" ``` *Will get the details for all fields that fits the search "VAT*" that belongs to the table with id 10347* ### **Get field details by searching for a field name across all tables** ``` Get-D365TableField -Name AccountNum -SearchAcrossTables ``` *Will search for the AccountNum field across all tables.* ## **Working with Azure Storage account** ### **Get all files from an Azure Storage account** ``` Get-D365AzureStorageFile -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Blobname "backupfiles" ``` *Get all files stored inside the **"backupfiles"** container / blob in the **"miscfiles"** storage account* ### **Upload a file to an Azure Storage account** ``` Invoke-D365AzureStorageUpload -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Blobname "backupfiles" -Filepath C:\temp\bacpac\UAT_20180701.bacpac -DeleteOnUpload ``` *This will upload the **"UAT_20180701.bacpac"** file to the specified Azure Storage Account and delete it when completed* ### **Download a file from an Azure Storage account** ``` Invoke-D365AzureStorageDownload -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Blobname "backupfiles" -FileName "UAT_20180701.bacpac" -Path "c:\temp" ``` *This will download the **"UAT_20180701.bacpac"** file from the Azure Storage Account and store it in "c:\temp\UAT_20180701.bacpac"* ## **Working with .NET classes and methods** ### **Get .NET class details by searching for a class name** ``` Get-D365DotNetClass -Name "ERText*" ``` *This will search across **all** assembly files (\*.dll) located in the package directory for any class that fits the search "**ERText\***"* ### **Get .NET class details by searching for a class name and searching for a file name** ``` Get-D365DotNetClass -Name "ERText*" -Assembly "*LocalizationFrameworkForAx.dll*" ``` *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\***"* ### **Get all methods available from an assembly** ``` Get-D365DotNetMethod -Assembly "C:\AOSService\PackagesLocalDirectory\ElectronicReporting\bin\Microsoft.Dynamics365.LocalizationFrameworkForAx.dll" ``` *This will search for all methods, across **all** classes, that exists inside the specified assembly file* ## **Working with installing binary updates, X++ hotfixes and 3. party ISV solutions** ### **Installation of binary updates** ``` Invoke-D365SDPInstall -Path C:\DeployablePackages -Command RunAll ``` *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* ### **Installation of 3. party ISV module - DevInstall** ``` Invoke-D365SDPInstall -Path C:\DeployablePackages -DevInstall ``` *This will execute the **"devinstall"** mode. The cmdlet expects the path "C:\DeployablePackages" to be the extracted directory from a package* ### **Installation of 3. party ISV module - QuickInstall** ``` Invoke-D365SDPInstall -Path C:\DeployablePackages -QuickInstall ``` *This will execute the **"QuickInstall"** mode. The cmdlet expects the path "C:\DeployablePackages" to be the extracted directory from a package* ### **Installation of X++ hotfix** ``` Invoke-D365SCDPBundleInstall -Path "c:\temp\HotfixPackageBundle.axscdppkg" ``` *This will execute the **"install"** mode without tfs / vsts parameters.* ## **Working with maintenance mode** ### **Enable maintenance mode** ``` Enable-D365MaintenanceMode ``` *This will put the environment into maintenance mode / state. Normally used when changing license configuration.* ### **Disable maintenance mode** ``` Disable-D365MaintenanceMode ``` *This will put the environment back into operation mode / state. Normally used when changing license configuration. **Note: You might need to stop and start your entire environment when done.*** ## **Working with installed services and topology files** ### **Get all installed services** ``` Get-D365InstalledService ``` *This will get all the installed services based on the installation logs. **Note: The cmdlet mimics the AxUpdateInstaller.exe -list command that also only reads the logs files*** ### **Create a new topology file and update it with ALMService,AOSService,BIService** ``` New-D365TopologyFile -Path C:\Temp\DefaultTopologyData.xml -Services "ALMService","AOSService","BIService" -NewPath C:\temp\CurrentTopology.xml ``` *This will read the "DefaultTopologyData.xml" file and update it with ALMService, AOSService and BIService* ### **Create a new topology file based on installed services** ``` $Services = @(Get-D365InstalledService | ForEach-Object {$_.Servicename}) New-D365TopologyFile -Path C:\Temp\DefaultTopologyData.xml -Services $Services -NewPath C:\temp\CurrentTopology.xml ``` *This will read the "DefaultTopologyData.xml" file and update it with the list of services from Get-D365InstalledService output* ## **Working with hotfixes** ### **Get all installed hotfixes** ``` Get-D365InstalledHotfix ``` *This will get all installed hotfixes on the machine and display all relevant information* ### **Get all installed hotfixes for specific module** ``` Get-D365InstalledHotfix -Model "*retail*" ``` *This will get all installed hotfixes that relates to models with retail in their name on the machine and display all relevant information* ### **Get all installed hotfixes for specific module and with specific KB number** ``` Get-D365InstalledHotfix -Model "*retail*" -KB "*43*" ``` *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* ## **Working with models** ### **Import a model file** ``` Invoke-D365ModelUtil -Path c:\temp\ApplicationSuiteModernDesigns_App73.axmodel ``` *This will import the **"c:\temp\ApplicationSuiteModernDesigns_App73.axmodel"** into the environment.* ***Note: Please note that you have to compile the application and run a db sync afterwards.*** ## **Working with environment configurations** ### **Initialize the D365FO.Tools configuration store** ``` Initialize-D365Config ``` *This will create the default configuration objects and set them to default values* ### **Add an environment configuration** ``` Add-D365EnvironmentConfig -Name "UAT" -URL "https://usnconeboxax1aos.cloud.onebox.dynamics.com/?cmp=USMF" -Company "USMF" ``` *This will add en entry named **"UAT"** with the **URL** and **Company** parameters.* ***Notes: This is the minimum you need to enabled a personal workstation to utilize Invoke-D365TableBrowser or Invoke-D365SysRunnerClass*** ### **Select an environment configuration as active** ``` Set-D365ActiveEnvironmentConfig -Name "UAT" ``` *This will get the environment details that is named UAT and put that into the active environment configuration.* ***Notes: You **MUST** restart the powershell session before using any cmdlets that depend on the configuration change.*** ### **Enabling the workstation mode** ``` Set-D365WorkstationMode -Enabled $true ``` *This will configure the module to be capable of running some of the cmdlets from a personal workstation tha is not an D365 environment* ***Notes: You **MUST** restart the powershell session before using any cmdlets that depend on the configuration change.*** ### **List all environment configurations** ``` Get-D365EnvironmentConfig ``` *This will show all stored environment configurations* ### **Get the active environment configuration** ``` Get-D365ActiveEnvironmentConfig ``` *This will the entire hashtable containing all the environment details* ### **Get the SqlPassword from the active environment configuration** ``` (Get-D365ActiveEnvironmentConfig).SqlPwd ``` *This will only return the SqlPwd value from the active configuration* ***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.*** ## **Working with Azure Storage Account configuration** ### **Add an Azure Storage Account configuration** ``` Add-D365AzureStorageConfig -Name "UAT-Exports" -AccountId "1234" -AccessToken "dafdfasdfasdf" -Blob "testblob" ``` *This will add en entry named **"UAT-Exports"** with the AccountId **1234**, AccessToken **dafdfasdfasdf** and Blob **testblob** parameters.* ### **Select an Azure Storage Account configuration as active** ``` Set-D365ActiveAzureStorageConfig -Name "UAT-Exports" ``` *This will get the environment details that is named **UAT-Exports** and put that into the active Azure Storage Account configuration.* ***Notes: You **MUST** restart the powershell session before using any cmdlets that depend on the configuration change.*** ### **List all Azure Storage Account configurations** ``` Get-D365AzureStorageConfig ``` *This will show all stored Azure Storage Account configurations* ### **Get the active Azure Storage Account configuration** ``` Get-D365ActiveAzureStorageConfig ``` *This will the entire hashtable containing all the Azure Storage Account details* ## **Working with AOT objects** ### **Search for all AxClasses in a package** ``` Get-D365AOTObject -ObjectType AxClass -Path "C:\AOSService\PackagesLocalDirectory\ApplicationFoundation" ``` *This will search for all AxClasses in the ApplicationFoundation package* ### **Search for specific AxClass in a package** ``` Get-D365AOTObject -Name "*flush*" -ObjectType AxClass -Path "C:\AOSService\PackagesLocalDirectory\ApplicationFoundation" ``` *This will search for all AxClasses in the ApplicationFoundation package that matches the search "\*flush\*"* ================================================ FILE: wiki/Open-the-path-where-D365FO.Tools-is-installed.md ================================================ Execute below command in powershell and an explorer window will open in the correct path ``` explorer.exe (Split-Path (Get-Module d365fo.tools).Path -Parent) ``` ================================================ FILE: wiki/Run-a-runnable-class.md ================================================ **You want to execute / run a runnable class** ``` Invoke-D365SysRunnerClass -ClassName SysDBInformation ``` *This will start a web browser and have it call the SysRunnerClass menu item with the SysDBInformation name of a runnable class* ``` Invoke-D365SysRunnerClass -ClassName SysDBInformation -Company USMF ``` *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* **Want to execute the SysFlushAod class** ``` Invoke-D365SysFlushAodCache ``` *This will start a web browser and have it call the SysRunnerClass menu item with the SysFlushAod name as the runnable class to execute* ================================================ FILE: wiki/Troubleshoot.md ================================================ 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. > **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. # General Powershell troubleshooting ## Check the versions ### d365fo.tools Check 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/). > *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. ### PowerShell Check which version of PowerShell is being used. This can be done with the `$PSVersionTable` variable. > *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. ### Other components Some 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. > *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. ## Use common parameters Powershell 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. > *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. ## Additional error details Even 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. > *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. ## **Record a PowerShell session** ```PS Start-Transcript -Path "C:\Temp\PowerShellSession.log" -Append ``` ## **Gathering logs** ```PS Get-PSFMessage -Errors | Format-List Get-PSFMessage -Errors | Format-List | Out-file c:\temp\errors.txt Get-PSFMessage -Level InternalComment | Format-List Get-PSFMessage -Level InternalComment | Format-List | out-file C:\temp\sqlcommands.txt ``` ## **Locate the folder where the module is installed** ```PS explorer.exe (Split-Path $(Get-Module d365fo.tools -ListAvailable | Select-Object -First 1).Path -Parent) ``` ## **Unsplat a hashtable to a string with parameters** ```PS ($HashArray.Keys | ForEach-Object {"-$($_) `"$($HashArray.Item($_))`""}) -Join " " ``` ## **Debug** For 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). To 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. ================================================ FILE: wiki/Tutorial-Import-Module.md ================================================ # **Import the d365fo.tools module** This tutorial will show you how to import the d365fo.tools on a machine where you already installed the d365fo.tools. You need to import / load the d365fo.tools module into PowerShell every time you need to use a command from it. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed Please 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. ## **Start PowerShell (Run As Administrator)** Locate 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. You need to right click on the PowerShell icon and select the "Run As Administrator" option for the menu. [[images/tutorials/First-Time-Start-PowerShell-Administrator.gif]] ## **Start PowerShell** Locate 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. [[images/tutorials/First-Time-Start-PowerShell-Non-Administrator.gif]] ## **Import module** You need to import / load the #d365fo.to module into the current PowerShell console. Type the following command: ``` Import-Module -Name d365fo.tools ``` [[images/tutorials/Import-Module-Administrator.gif]] ## **Closing comments** In this tutorial we showed you how to import the d365fo.tools into your PowerShell console. ================================================ FILE: wiki/Tutorial-Install-Administrator.md ================================================ # **Install as a Administrator** This tutorial will show you how to install the d365fo.tools on a machine where you have administrator access / privileges. If 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. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * Administrator privileges * Internet access / Internet connection ## **Logon to the computer** You need sign into the machine where you want to install the tools. Remember to sign in as an account with administrator privileges. If 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. ## **Start PowerShell (Run As Administrator)** Locate 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. You need to right click on the PowerShell icon and select the "Run As Administrator" option for the menu. [[images/tutorials/First-Time-Start-PowerShell-Administrator.gif]] ## **Install the d365fo.tools module** In the PowerShell console/window type the following command: ``` Install-Module -Name d365fo.tools ``` [[images/tutorials/First-Time-Install-Administrator-Install-Module.gif]] PowerShell 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. You 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. ### **NuGet** If you want to learn about NuGet as concept, you can start here: https://en.wikipedia.org/wiki/NuGet Answer the prompt with: **Y** [[images/tutorials/First-Time-Install-Administrator-Confirm-Nuget.gif]] ### **Untrusted Repository** The 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 Answer the prompt with: **A** [[images/tutorials/First-Time-Install-Administrator-Confirm-Repository.gif]] ## **Completing installation** [[images/tutorials/First-Time-Install-Administrator-Wait-For-Installation.gif]] ## **Import module** While 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: ``` Import-Module -Name d365fo.tools ``` [[images/tutorials/First-Time-Install-Administrator-Import-Module.gif]] ## **Closing comments** In 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. ================================================ FILE: wiki/Tutorial-Install-Non-Administrator.md ================================================ # **Install as a non-Administrator** This tutorial will show you how to install the d365fo.tools on a machine where you **don't** have administrator access / privileges. If 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. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * Internet access / Internet connection ## **Logon to the computer** You need sign into the machine where you want to install the tools. If 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. ## **Start PowerShell** Locate 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. [[images/tutorials/First-Time-Start-PowerShell-Non-Administrator.gif]] ## **Install the d365fo.tools module** In the PowerShell console/window type the following command: ``` Install-Module -Name d365fo.tools -Scope CurrentUser ``` [[images/tutorials/First-Time-Install-Non-Administrator-Install-Module.gif]] PowerShell 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. You 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. ### **NuGet** If you want to learn about NuGet as concept, you can start here: https://en.wikipedia.org/wiki/NuGet Answer the prompt with: **Y** [[images/tutorials/First-Time-Install-Non-Administrator-Confirm-Nuget.gif]] ### **Untrusted Repository** The 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 Answer the prompt with: **A** [[images/tutorials/First-Time-Install-Non-Administrator-Confirm-Repository.gif]] ## **Completing installation** [[images/tutorials/First-Time-Install-Non-Administrator-Wait-For-Installation.gif]] ## **Import module** While 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: ``` Import-Module -Name d365fo.tools ``` [[images/tutorials/First-Time-Install-Non-Administrator-Import-Module.gif]] ## **Closing comments** In 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. ================================================ FILE: wiki/Tutorial-List-Commands.md ================================================ # **List available commands from d365fo.tools module** This tutorial will show you how to list and search for commands that are available from the d365fo.tools module. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed Please 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. ## **Start PowerShell** Locate 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. [[images/tutorials/First-Time-Start-PowerShell-Non-Administrator.gif]] ## **Import module** You need to import / load the d365fo.tools module into the current PowerShell console. Type the following command: ``` Import-Module -Name d365fo.tools ``` [[images/tutorials/Import-Module-Administrator.gif]] ## **List all available commands** If 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: ``` Get-Command -Module d365fo.tools ``` [[images/tutorials/First-Time-List-Commands.gif]] ## **Search for commands** If 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: ``` Get-Command *bacpac* -Module d365fo.tools ``` [[images/tutorials/First-Time-Search-Commands.gif]] ## **Closing comments** In 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. ================================================ FILE: wiki/Tutorial-Show-Help.md ================================================ # **Get help content for a command** This tutorial will show you how to get the different kind of help content available for every command in the d365fo.tools module. ## **Prerequisites** * Machine with D365FO installed * PowerShell 5.1 * d365fo.tools module installed Please 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. ## **Start PowerShell** Locate 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. [[images/tutorials/First-Time-Start-PowerShell-Non-Administrator.gif]] ## **Import module** You need to import / load the d365fo.tools module into the current PowerShell console. Type the following command: ``` Import-Module -Name d365fo.tools ``` [[images/tutorials/Import-Module-Administrator.gif]] ## **List all available commands** For us to have something to work with, we need to get the list of available functions in the module. Type the following command: ``` Get-Command -Module d365fo.tools ``` [[images/tutorials/First-Time-List-Commands.gif]] ## **Get help content for a specific function** If 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: ``` Get-Help New-D365Bacpac ``` [[images/tutorials/First-Time-Show-Help.gif]] ## **Get help content, including examples, for a specific function** The help content for every function contains a high level explanation for each available parameter and examples. Type the following command: ``` Get-Help New-D365Bacpac -Full ``` [[images/tutorials/First-Time-Show-Help-Full.gif]] ## **Get examples only, for a specific function** The help content for every function contains at least 1 example on how run the function. Type the following command: ``` Get-Help New-D365Bacpac -Examples ``` [[images/tutorials/First-Time-Show-Help-Examples-Only.gif]] ## **Closing comments** In this tutorial we showed you how to list help content for a specific command, including the detailed parameter explanation and the examples. ================================================ FILE: wiki/Update-users-in-environment.md ================================================ 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**)? You just restored your **PROD** / **UAT** environment to a Azure hosted or a local VM (onebox)? Now you need to grant access (back) to your users in the restored environment and you want to do it without all the mouse clicking? Look no further! We assume: * That you already did run the `Install-Modele -Name d365fo.tools` on the machine / server you will be using for this. * 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). For 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" 1. Start PowerShell (Start Menu - type powershell and click enter when you see the icon marked) 2. Run `Import-Module d365fo.tools` 3. Run `Set-D365Admin "insertyouremailaddress"` - Remember that the e-mail address needs to be a valid Azure Active Directory e-mail - E.g. `Set-D365Admin "allen@contoso.com"` 4. Wait for the command to finish 5. Run `Update-D365User -Email "%youremaildomain%"` - Fill in the domain of the users that you want to update and give back access to the specific environment - E.g. `Update-D365User -Email "%contoso.com%"` ================================================ FILE: wiki/Utilizing-the-configuration-system.md ================================================ The d365fo.tools module is built upon the foundation of the **PSFramework**, which enables a full blown configuration store for PowerShell modules and scripts. A 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. We have several configuration sub sections: * Environment * Azure Storage Account * Azure Logic App ## **Environment Configuration Store** The environment configuration store is a multi array store, that can store different environment details, per environment, for your convenience. The 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. The TfsUri parameter is designed to support a developer working with hotfixes and installation, that needs to check in code against VSTS / Azure DevOps. The 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. **Available cmdlets / functions** * Add-D365EnvironmentConfig * Get-D365EnvironmentConfig * Get-D365ActiveEnvironmentConfig * Set-D365ActiveEnvironmentConfig ### **Add-D365EnvironmentConfig** `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` It is **not** necessary to fill in all the details when using the `Add-D365EnvironmentConfig` **Example on how to fill out the details for every parameter.** This will create a environment configuration that is stored with the name "TEST" ``` $params = @{} $params.URL = (Get-D365Url).Url $params.SqlUser = "sqladmin" $params.SqlPwd = "afafKHkhke" $params.Company = "DAT" $params.TfsUri = (Get-D365TfsUri).TfsUri Add-D365EnvironmentConfig -Name TEST @params ``` ### **Get-D365EnvironmentConfig** `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` **Example on how to list all environments** ``` Get-D365EnvironmentConfig Name : TEST TfsUri : https://projectname.visualstudio.com/ URL : https://usnconeboxax1aos.cloud.onebox.dynamics.com/ Company : DAT SqlUser : sqladmin SqlPwd : afafKHkhke ``` ### **Set-D365ActiveEnvironmentConfig** `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` **Example on how to set a given environment af the active environment configuration** ``` Set-D365ActiveEnvironmentConfig -Name TEST ``` ### **Get-D365ActiveEnvironmentConfig** `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` **Example on how to see the current active environment and its details** ``` Get-D365ActiveEnvironmentConfig Name Value ---- ----- TfsUri https://projectname.visualstudio.com/ URL https://usnconeboxax1aos.cloud.onebox.dynamics.com/ Company DAT SqlUser sqladmin SqlPwd afafKHkhke ``` ================================================ FILE: wiki/Work-with-Azure-Storage-Account.md ================================================ 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. Look no further! We assume: * You already have an active Azure Storage Account * You already have created the needed tokens for the Azure Storage Account You 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**. 1. Start PowerShell (Start Menu - type powershell and click enter when you see the icon marked) 2. Run `Import-Module d365fo.tools` **Note:** *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.* **Listing files** ``` Get-D365AzureStorageFile -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Blobname "backupfiles" ``` *This will get the details of all the files stored in the **"backupfiles"** blob / container inside the **"miscfiles"** Azure Storage Account* ``` Get-D365AzureStorageFile -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Blobname "backupfiles" -Name "*UAT*" ``` *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* **Downloading files** ``` Invoke-D365AzureStorageDownload -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Blobname "backupfiles" -FileName "OriginalUAT.bacpac" -Path "c:\temp" ``` *This will download the **"OriginalUAT.bacpac"** file from the Azure Storage Account and store it in **"c:\temp\OriginalUAT.bacpac"**. ``` Invoke-D365AzureStorageDownload -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Blobname "backupfiles" -Path "c:\temp" -GetLatest ``` *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. **Uploading files** ``` Invoke-D365AzureStorageUpload -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Blobname "backupfiles" -Filepath "c:\temp\bacpac\UAT_20180701.bacpac" -DeleteOnUpload ``` *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.* **Advanced scenarios** ``` Get-D365AzureStorageFile -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Blobname "backupfiles" -Name "*UAT*" | Invoke-D365AzureStorageDownload -AccountId "miscfiles" -AccessToken "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51" -Blobname "backupfiles" -Path "c:\temp" ``` *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.* ================================================ FILE: wiki/Work-with-packages,-resource---label-files,-language-and-lables.md ================================================ **Work with packages, label files, language and labels** ``` Get-D365InstalledPackage ``` *Gets all installed packages on the system/machine* ``` Get-D365InstalledPackage -Name "ApplicationSuite" ``` *Gets the "ApplicationSuite" package* ``` Get-D365InstalledPackage -Name "ApplicationSuite" | Get-D365PackageLabelFile -Language "en-US" ``` *Gets all the "en-US" resource / label files from the ApplicationSuite package* ``` Get-D365InstalledPackage -Name "ApplicationSuite" | Get-D365PackageLabelFile -Language "en-US" -Name "PRO" ``` *Gets the PRO resource / label file from the "ApplicationSuite" package with the language "EN-US"* ``` Get-D365InstalledPackage -Name "ApplicationSuite" | Get-D365PackageLabelFile -Language "en-US" -Name "PRO" | Get-D365Label ``` *Gets all label details from the PRO resource / label file from the "ApplicationSuite" package with the language "EN-US"* ``` Get-D365InstalledPackage -Name "ApplicationSuite" | Get-D365PackageLabelFile -Language "*" -Name "PRO" | Get-D365Label -Name "@PRO505" ``` *Gets the "@PRO505" label details from the "PRO" resource / label file from the "ApplicationSuite" package, **across all languages*** ``` Get-D365InstalledPackage -Name "ApplicationSuite" | Get-D365PackageLabelFile -Language "en-US" | Get-D365Label -Value "*qty*" -IncludePath ``` *Gets all "en-US" labels where the value contains "*qty*" from the "ApplicationSuite" package, **across all resource / label files*** ``` Get-D365InstalledPackage | Out-GridView -PassThru | Get-D365PackageLabelFile -Language "da" | Out-GridView -PassThru | Get-D365Label -IncludePath | Out-GridView ``` *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.* ``` Get-D365InstalledPackage | Get-D365PackageLabelFile -Language "da" | Get-D365Label -Value "*antal*" -IncludePath | Out-GridView ``` *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* ================================================ FILE: wiki/Work-with-tables-and-fields.md ================================================ So you are working with troubleshooting or maybe extending Dynamics 365 Finance & Operations. * You might have a TableId and want to know what table(name) is behind that id. * You might have a table(name) and want to know what TableId is behind that table name. * You might have a TableId and FieldId and want to know what hides behind different ids. * You might have a table(name) and want to know what fields are part of the table. * You might have part of a field(name) and want to search all tables for a matching field. Look no further! We assume: * That you already did run the `Install-Modele -Name d365fo.tools` on the machine / server you will be using for this. * That you will be running this from a Tier 1 machine /environment or one the AOS machines / Servers in the Tier 2 environment. 1. Start PowerShell (Start Menu - type powershell and click enter when you see the icon marked) 2. Run `Import-Module d365fo.tools` **You want to search for CustTable, either by TableId or TableName** ``` Get-D365Table -Id 10347 ``` *You only have the TableId: 10347 on your hands and your memory doesn't seem to remember that this is actually CustTable* ``` Get-D365Table -Name CustTable ``` *You only have the "CustTable" on your hands and your memory doesn't seem to remember that this is actually TableId: 10347* **You want to see all fields for CustTable, either by TableId or TableName** ``` Get-D365TableField -TableId 10347 #OR Get-D365TableField -TableId 10347 -IncludeTableDetails | Format-Table ``` *You only have the TableId: 10347 on your hands and you can't remember all fields that is part of that table* ``` Get-D365TableField -TableName CustTable #OR Get-D365TableField -TableName CustTable -IncludeTableDetails | Format-Table ``` *You only have the "CustTable" on your hands and you can't remember all fields that is part of that table* **You want to see a specific field for CustTable, either by TableId or TableName, and either by FieldId or FieldName** ``` Get-D365TableField -TableId 10347 -FieldId 175 #OR Get-D365TableField -TableId 10347 -Name vatnum ``` *You only have the TableId: 10347 on your hands and you can't the FieldId or FieldName for VATNUM* ``` Get-D365TableField -TableName CustTable -FieldId 175 #OR Get-D365TableField -TableName CustTable -Name vatnum ``` *You only have the "CustTable" on your hands and you can't the FieldId or FieldName for VATNUM* ## **You are ready to take your PowerShell skills to the next level** ``` Get-D365Table -Name CustTable,CustTrans | Get-D365TableField -Name Accountnum -IncludeTableDetails | Format-Table ``` *You want to search for a Column(name) / Field(name) across multiple **known** tables* ``` Get-D365Table -Name CustTable,CustTrans | Get-D365TableField -IncludeTableDetails | Format-Table ``` *You want to see all fields across multiple **known** tables* ``` Get-D365TableField -Name AccountNum -SearchAcrossTables | Get-D365TableField -IncludeTableDetails | Format-Table ``` *You want to search for a Column(name) / Field(name) across **all** tables and include the full details* ***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* ``` Get-D365TableField -Name "Account*" -SearchAcrossTables | Format-List ``` *You want to search for a Column(name) / Field(name) across **all** tables* **Small teaser for the combination of Get-D365Table and Invoke-D365TableBrowser** ``` Get-D365Table -Name CustTable,CustTrans | Invoke-D365TableBrowser -Company USMF ``` *You want to start the table browser for **both** CustTable & CustTrans, against the USMF company* ================================================ FILE: wiki/Working-with-the-different-D365-services.md ================================================ So you are working on a project where you have to export/import a bacpac file from any NON-PROD environment. You 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. Look no further! We assume: * That you already did run the `Install-Module -Name d365fo.tools` on the machine / server you will be using for this. * That you will be running this from 1 of the AOS machines / Servers in the Tier 2 environment. 1. Start PowerShell (Start Menu - type powershell and click enter when you see the icon marked) 2. Run `Import-Module d365fo.tools` **Tier-1 examples** Run `Get-D365Environment -All` *This will display the current status of all the D365 services on the machine* Run `Stop-D365Environment -All` *This stop all the D365 services on the machine. It will list the current status for all services* Run `Start-D365Environment -All` *This start all the D365 services on the machine. It will list the current status for all services* **Tier-2 examples** Run `Get-D365Environment -ComputerName "TEST-SB-AOS1","TEST-SB-AOS2","TEST-SB-BI1" -All` *This will display the current status of all the D365 services across all the supplied machines.* Run `Stop-D365Environment -ComputerName "TEST-SB-AOS1","TEST-SB-AOS2","TEST-SB-BI1" -All` *This stop all the D365 services across all the supplied machines. It will list the current status for all services* Run `Start-D365Environment -ComputerName "TEST-SB-AOS1","TEST-SB-AOS2","TEST-SB-BI1" -All` *This start all the D365 services across all the supplied machines. It will list the current status for all services* ================================================ FILE: wiki/_Sidebar.md ================================================ # **Learn** ## **Tutorials** * [Install as a non-Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Non-Administrator) * [Install as a Administrator](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Install-Administrator) * [Import d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Import-Module) * [List available commands from d365fo.tools module](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-List-Commands) * [Get help content for a command](https://github.com/d365collaborative/d365fo.tools/wiki/Tutorial-Show-Help) ## **How To** * [Start, Stop and List services](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Start-Stop-List-D365FO-Services) * [Import users into the D365FO environment](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Import-User-Into-Db) * [Import external users into the D365FO environment](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Import-External-User-Into-Db) * [Enable users in the D365FO environment](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Enable-Users-In-Db) * [Update users in the D365FO environment](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Update-Users-In-Db) * [Provision D365FO environment to new Azure AD tenant](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Provision-Environment-Tier1) * [Import a bacpac file into a Tier1 environment](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Import-Bacpac-Into-Tier1) * [List modules / models](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-List-Models) * [Compile module](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Compile-Model) * [Install AzCopy](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Install-AzCopy) * [Install SqlPackage](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Install-SqlPackage) * [Install Nuget](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Install-Nuget) * [Speed up LCS download via AzCopy](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Transfer-Via-AzCopy) * [Download latest bacpac from LCS via AzCopy](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Download-Latest-Bacpac-From-Lcs) * [Register NuGet source](https://github.com/d365collaborative/d365fo.tools/wiki/How-To-Register-Nuget-Source) ## **Guides** * [[Configure Azure Logic App]] * [[Fix AzureStorageConfig]] * [[Run a runnable class]] * [[Update users in environment]] * [[Work with Azure Storage Account]] * [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) * [[Working with the different D365 services]] # **Documentation** ## **Concepts** ### **Automation** * [[Exception handling]] ### **Configuration** * [[Configuration]] # **Contribute** ## **Start Here** * [[Do And Do Not]] * [[Implementing the messaging system]] * [[Getting Started with GitHub]] * [Your First Pull Request](https://github.com/sqlcollaborative/dbatools/wiki/Your-First-Pull-Request) * [[Removing a file from your PR]] * [[Style Guide]] * [[Branching]] * [[Azure DevOps Build Configuration]] * [[Building-tools]] * [[How To Write Wiki Pages]] ## **Quality Control** * [[Testing & QA]] ## **Automated Testing** * [[Appveyor and tests]] ## **Deprecation** * [[Deprecation guidelines]] ## **Troubleshooting** * [[Troubleshoot]] * [[Load individual files or dot source the files]]