{"id":2114,"date":"2025-04-22T08:30:00","date_gmt":"2025-04-22T07:30:00","guid":{"rendered":"https:\/\/kasperjohansen.net\/?p=2114"},"modified":"2025-04-20T13:47:53","modified_gmt":"2025-04-20T12:47:53","slug":"migrate-psadt-3-x-apps-to-psadt-4-x","status":"publish","type":"post","link":"https:\/\/kasperjohansen.net\/index.php\/2025\/04\/22\/migrate-psadt-3-x-apps-to-psadt-4-x\/","title":{"rendered":"Migrate PSADT 3.x apps to PSADT 4.x"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Late last year a new release of the Powershell AppDeploy Toolkit (PSADT) surfaced. The application deployment framework is at the time of writing on version 4.0.6 and compared to version 3.x, it has received a major overhaul on almost all areas. In a coming article I will cover some of the changes in the new PSADT 4.x. However, in this article I will show how to convert an existing PSADT 3.x based application to PSADT 4.x. using the <a href=\"https:\/\/psappdeploytoolkit.com\/docs\/getting-started\/download#installing-from-the-powershell-gallery\">PSAppDeployToolkit <\/a>and <a href=\"https:\/\/psappdeploytoolkit.com\/docs\/getting-started\/download#downloading-psappdeploytoolkittools\">PSAppDeployToolkit.Tools<\/a> Powershell modules.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you are not familiar with the Powershell AppDeploy Toolkit framework, I have written a 3-part article on how get started with streamlining application management with PSADT and Microsoft Intune. Get started with part 1 of the articles <a href=\"https:\/\/kasperjohansen.net\/index.php\/2024\/10\/21\/streamlining-application-management-with-psadt-and-microsoft-intune-part-1\/\" data-type=\"link\" data-id=\"https:\/\/kasperjohansen.net\/index.php\/2024\/10\/21\/streamlining-application-management-with-psadt-and-microsoft-intune-part-1\/\">here<\/a>.<\/p>\n\n\n\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-transparent ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/kasperjohansen.net\/index.php\/2025\/04\/22\/migrate-psadt-3-x-apps-to-psadt-4-x\/#PSADTv3_migration\" >PSADTv3 migration<\/a><ul class='ez-toc-list-level-3' ><li class='ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/kasperjohansen.net\/index.php\/2025\/04\/22\/migrate-psadt-3-x-apps-to-psadt-4-x\/#Prerequisites\" >Prerequisites<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/kasperjohansen.net\/index.php\/2025\/04\/22\/migrate-psadt-3-x-apps-to-psadt-4-x\/#The_script\" >The script<\/a><ul class='ez-toc-list-level-4' ><li class='ez-toc-heading-level-4'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/kasperjohansen.net\/index.php\/2025\/04\/22\/migrate-psadt-3-x-apps-to-psadt-4-x\/#Script_parameters\" >Script parameters<\/a><ul class='ez-toc-list-level-5' ><li class='ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/kasperjohansen.net\/index.php\/2025\/04\/22\/migrate-psadt-3-x-apps-to-psadt-4-x\/#SourceAppFolder\" >SourceAppFolder<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/kasperjohansen.net\/index.php\/2025\/04\/22\/migrate-psadt-3-x-apps-to-psadt-4-x\/#NewAppFolder\" >NewAppFolder<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/kasperjohansen.net\/index.php\/2025\/04\/22\/migrate-psadt-3-x-apps-to-psadt-4-x\/#NewAppMediaFolderName\" >NewAppMediaFolderName<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-5'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/kasperjohansen.net\/index.php\/2025\/04\/22\/migrate-psadt-3-x-apps-to-psadt-4-x\/#NewAppLogPath\" >NewAppLogPath<\/a><\/li><\/ul><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/kasperjohansen.net\/index.php\/2025\/04\/22\/migrate-psadt-3-x-apps-to-psadt-4-x\/#Seeing_is_believing\" >Seeing is believing<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"PSADTv3_migration\"><\/span>PSADTv3 migration<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Prerequisites\"><\/span>Prerequisites<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">As mentioned, the migration script makes use of the PSAppDeployToolkit and PSAppDeployToolkit.Tools modules, so they have to be installed before executing the migration script. <br><br>Currently, the PSAppDeployToolkit.Tools module is in a Pre-Release stage, which means the -AllowPrerelease parameter needs to be appended the Import-Module command:<br><\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Install-Module PSAppDeployToolkit.Tools -Scope CurrentUser -AllowPreRelease<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In this case I am also using the -CurrentUser parameter, which will import the module in user context which does not require local administrative privileges.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Executing above mentioned command might lead to this magnificent error message:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"248\" src=\"https:\/\/kasperjohansen.net\/wp-content\/uploads\/2025\/04\/PoSH-error-01-1024x248.jpg\" alt=\"\" class=\"wp-image-2125\" srcset=\"https:\/\/kasperjohansen.net\/wp-content\/uploads\/2025\/04\/PoSH-error-01-1024x248.jpg 1024w, https:\/\/kasperjohansen.net\/wp-content\/uploads\/2025\/04\/PoSH-error-01-300x73.jpg 300w, https:\/\/kasperjohansen.net\/wp-content\/uploads\/2025\/04\/PoSH-error-01-768x186.jpg 768w, https:\/\/kasperjohansen.net\/wp-content\/uploads\/2025\/04\/PoSH-error-01.jpg 1203w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This message means that the current version of the PowershellGet module is not version 2.2.5 or later. <br><strong>This means, before executing the migration script you will have to update the PowershellGet module, otherwise the script will fail!<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To update the PowershellGet module and avoid uncomfortable questions like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"250\" src=\"https:\/\/kasperjohansen.net\/wp-content\/uploads\/2025\/04\/PoSH-info-01-1024x250.jpg\" alt=\"\" class=\"wp-image-2126\" srcset=\"https:\/\/kasperjohansen.net\/wp-content\/uploads\/2025\/04\/PoSH-info-01-1024x250.jpg 1024w, https:\/\/kasperjohansen.net\/wp-content\/uploads\/2025\/04\/PoSH-info-01-300x73.jpg 300w, https:\/\/kasperjohansen.net\/wp-content\/uploads\/2025\/04\/PoSH-info-01-768x187.jpg 768w, https:\/\/kasperjohansen.net\/wp-content\/uploads\/2025\/04\/PoSH-info-01.jpg 1202w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">&#8230;a series of commands can be used:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Set-PSRepository -Name PSGallery -InstallationPolicy Trusted # Trust the Microsoft PSGallery\nInstall-PackageProvider -Name NuGet -Force -Scope CurrentUser # Install the latest NuGet package provider\nInstall-Module PowerShellGet -Force -Scope CurrentUser -AllowClobber # Install the latest PowershellGet module<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The first line adds the PSGallery as a trusted source, the second line installs the NuGet package provider and the third installs or updates the PowershellGet module. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hopefully everything will go through successfully. Afterwards the current Powershell\/Terminal console must be closed to reinitialize the installed\/updated PowershellGet command.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"The_script\"><\/span>The script<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The script file contains information and examples on how to execute the script. However, I will just go through the 4 supported and needed parameters, to give a bit of context and share my thoughts about how the script can\/should be used.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Script_parameters\"><\/span>Script parameters<span class=\"ez-toc-section-end\"><\/span><\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The SourceAppFolder and NewAppFolder parameters are mandatory, whereas the NewAppMediaFoldername and NewAppLogPath parameters are not.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"SourceAppFolder\"><\/span>SourceAppFolder<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">The source folder where one or more PSADTv3 based applications are located. The script will do a recursive list of folders and store the folder name as a variable. This folder name will be the same for the new converted PSADTv4 application.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"NewAppFolder\"><\/span>NewAppFolder<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">The destination folder where the new converted PSADTv4 app should be created. <\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"NewAppMediaFolderName\"><\/span>NewAppMediaFolderName<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">This will create a subfolder in the NewAppFolder, which will contain both the application source files and the PSADTv4 framework script<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"NewAppLogPath\"><\/span>NewAppLogPath<span class=\"ez-toc-section-end\"><\/span><\/h5>\n\n\n\n<p class=\"wp-block-paragraph\">This will change the default log path location.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A script syntax could look like this:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">.\\Migrate-PSADTv3App -SourceAppFolder \"C:\\temp\\PSADTv3\" -NewAppFolder \"C:\\temp\\PSADTv4\" -NewAppMediaFolderName \"Media\" -NewAppLogPath \"C:\\ProgramData\\Microsoft\\IntuneManagementExtension\\Logs\"<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is one of the examples mentioned in the script file. <br>This will migrate all PSADTv3 based applications in the <em>C:\\temp\\PSADTv3<\/em> folder to the <em>C:\\temp\\PSADTv4\\Media<\/em> folder and change the default log file location to <em>C:\\ProgramData\\Microsoft\\IntuneManagementExtension\\Logs<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you don&#8217;t want or need the &#8220;Media&#8221;, you can omit the -NewAppMediaFolder parameter:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">.\\Migrate-PSADTv3App -SourceAppFolder \"C:\\temp\\PSADTv3\" -NewAppFolder \"C:\\temp\\PSADTv4\" -NewAppLogPath \"C:\\ProgramData\\Microsoft\\IntuneManagementExtension\\Logs\"<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This will migrate all PSADTv3 based applications in the <em>C:\\temp\\PSADTv3<\/em> folder to the <em>C:\\temp\\PSADTv4 <\/em>folder and change the default log file location to <em>C:\\ProgramData\\Microsoft\\IntuneManagementExtension\\Logs<\/em>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Seeing_is_believing\"><\/span>Seeing is believing<span class=\"ez-toc-section-end\"><\/span><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">I have created a small screen recording showing the migration script in action.<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video height=\"998\" style=\"aspect-ratio: 1906 \/ 998;\" width=\"1906\" controls src=\"https:\/\/kasperjohansen.net\/wp-content\/uploads\/2025\/04\/PSADTv3Migration.mp4\"><\/video><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Here I am demonstrating the PSADTv3 migration of Citrix Workspace App and Notepad++ to PSADTv4. The script is migrating the source files and converting both the install  and uninstall syntaxes to the new cmdlets in PSADTv4. The log path for both MSI file deployment and the toolkit itself is also configured.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can get the script from my Github repo &#8211; <a href=\"https:\/\/github.com\/kaspersmjohansen\/Microsoft-Intune\/tree\/master\/Scripts\/Migrate%20PSADTv3%20to%20PSADTv4\">Microsoft-Intune\/Scripts\/Migrate PSADTv3 to PSADTv4 at master \u00b7 kaspersmjohansen\/Microsoft-Intune<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Test it out and let me know if you run into any issues or if you have feature requests.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This concludes the article. Feel free to reach out to me on\u00a0<a href=\"https:\/\/twitter.com\/KasperMJohansen\">X<\/a>\u00a0or on\u00a0<a href=\"https:\/\/www.linkedin.com\/in\/kaspermjohansen\/\">LinkedIn<\/a>\u00a0if you have any comments or questions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Late last year a new release of the Powershell AppDeploy Toolkit (PSADT) surfaced. The application deployment framework is at the time of writing on version 4.0.6 and compared to version &#8230;<\/p>\n","protected":false},"author":2,"featured_media":2143,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,6,32],"tags":[],"class_list":["post-2114","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-apps","category-intune","category-scripts"],"_links":{"self":[{"href":"https:\/\/kasperjohansen.net\/index.php\/wp-json\/wp\/v2\/posts\/2114","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kasperjohansen.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kasperjohansen.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kasperjohansen.net\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/kasperjohansen.net\/index.php\/wp-json\/wp\/v2\/comments?post=2114"}],"version-history":[{"count":15,"href":"https:\/\/kasperjohansen.net\/index.php\/wp-json\/wp\/v2\/posts\/2114\/revisions"}],"predecessor-version":[{"id":2142,"href":"https:\/\/kasperjohansen.net\/index.php\/wp-json\/wp\/v2\/posts\/2114\/revisions\/2142"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/kasperjohansen.net\/index.php\/wp-json\/wp\/v2\/media\/2143"}],"wp:attachment":[{"href":"https:\/\/kasperjohansen.net\/index.php\/wp-json\/wp\/v2\/media?parent=2114"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kasperjohansen.net\/index.php\/wp-json\/wp\/v2\/categories?post=2114"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kasperjohansen.net\/index.php\/wp-json\/wp\/v2\/tags?post=2114"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}