{"id":1763,"date":"2020-03-12T22:57:00","date_gmt":"2020-03-12T22:57:00","guid":{"rendered":"https:\/\/ricardomoinhos.com\/?p=1763"},"modified":"2020-03-29T00:53:44","modified_gmt":"2020-03-29T00:53:44","slug":"c-al-to-al-data-upgrade-automation-powershell-script","status":"publish","type":"post","link":"https:\/\/ricardomoinhos.com\/pt\/c-al-to-al-data-upgrade-automation-powershell-script\/","title":{"rendered":"C\/AL to AL Data Upgrade Automation Powershell Script"},"content":{"rendered":"\n<p>Eric Walters (Waldo) shared a great tool developed \u201con top of\u201d the existing Microsoft.Dynamics.Nav.Model.Tools.dll, which is a library that serves the PowerShell Merge-CmdLets provided by Microsoft, that allow us to do a bunch of analysis on top of NAV\/BC objects (man, you rock!).<\/p>\n\n\n\n<p>More info here: <a href=\"https:\/\/www.waldo.be\/2019\/02\/15\/c-al-source-code-analysis-with-powershell\/\">https:\/\/www.waldo.be\/2019\/02\/15\/c-al-source-code-analysis-with-powershell\/<\/a><\/p>\n\n\n\n<p>And here: <a href=\"https:\/\/github.com\/waldo1001\/Waldo.Model.Tools\">https:\/\/github.com\/waldo1001\/Waldo.Model.Tools<\/a><\/p>\n\n\n\n<p>I have created a script that uses this great tool and automates part of the objects creation needed in the data migration process.<\/p>\n\n\n\n<p>The script is available in GitHub and a pull request will be made. Hopefully Waldo will accept it and include it in the original repo.<\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/ricardopaiva\/Waldo.Model.Tools\/tree\/feature\/data_migration_demo\">https:\/\/github.com\/ricardopaiva\/Waldo.Model.Tools\/tree\/feature\/data_migration_demo<\/a><\/p>\n\n\n\n<p>Branch: feature\/data_migration_demo<\/p>\n\n\n\n<p>Added files: <strong>DataMigrationModule.psm1<\/strong> and <strong>DataMigrationScript.ps1<\/strong> in <strong>Data Migration<\/strong> folder.<\/p>\n\n\n\n<p><strong>UPDATE 2020\/03\/29:<\/strong> I&#8217;ve made a few updates in the script. Table filtering is now possible as well. Waldo accepted and merged both pull requests so check the most recent version in his GitHub page: <a href=\"https:\/\/github.com\/waldo1001\/Waldo.Model.Tools\">https:\/\/github.com\/waldo1001\/Waldo.Model.Tools<\/a><\/p>\n\n\n\n<p>To give you context, I&#8217;ve made a data upgrade from C\/AL to AL (NAV 2009 to Business Central v14). If you want to know how I handled the data migration from C\/AL tables to AL table extensions, please take a look at the following article in my blog: <a href=\"https:\/\/ricardomoinhos.com\/c-side-to-al-table-data-migration\/\">https:\/\/ricardomoinhos.com\/c-side-to-al-table-data-migration\/<\/a><\/p>\n\n\n\n<p>The script I&#8217;ve created automates the following steps:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Creation of the temp tables (used to migrate data in custom fields, from the actual tables to the temp tables);<\/li><li>Creation of the C\/AL data migration codeunit (used to migrate data in custom fields, from the actual tables to the temp tables created earlier);<\/li><li>Creation of the AL data migration codeunit (used to migrate in from custom fields, from temp tables to the final fields in table extensions);<\/li><li>Also, there&#8217;s a function available to create a CSV with all objects\/fields processed, just in case you need to, for example, list all custom fields.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">How to use<\/h2>\n\n\n\n<ol class=\"wp-block-list\"><li>Make sure that the Waldo&#8217;s tool is installed and working;<\/li><li>Edit _LoadObjects.ps1 and update the objects file path in the first line;<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">$ObjectsFile = \"Objects Folder\\Objects.txt\" #point to a file that exists for you (advised to create a complete text-export of an BC\/NAV Database)\n$ModuleToolAPIPath = Join-Path $PSScriptRoot \"The Magic\\NavModelToolsAPI.dll\"\nimport-module $ModuleToolAPIPath -WarningAction SilentlyContinue -Verbose\n$Model = Get-NAVObjectModel -NavObjectsTextFile $ObjectsFile -TimeExecution\nWrite-Host $Model.NAVObjects.Count <\/pre>\n\n\n\n<ol class=\"wp-block-list\" start=\"3\"><li>Run the _LoadObjects.ps1 script to load the objects model in memory before running the DataMigrationScript.ps1. This script file is part of Waldo\u2019s tool and you can run it or you can copy the content to your own script file (you can copy the content of this file to the DataMigrationScript.ps1 if you want)<\/li><li>Update and run the DataMigrationScript.ps1 file, according to your needs;<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">$DataMigrationModulePath = Join-Path $PSScriptRoot \"DataMigrationModule.psm1\"\nImport-Module $DataMigrationModulePath -WarningAction SilentlyContinue -Verbose -Force\nif ($Model.NAVObjects.Count -eq 0) {\n   Write-Host -ForegroundColor Red \"No objects were found. Load objects first using _LoadObjects.ps1 script\"\n   return\n}\n\nCreateCALFieldsCSV 'C:\\Temp\\ObjectsAnalysis.csv' `\n                   -fieldFilter '50000..90000|31000000..31099999'\nCreateCALTempTables 'C:\\Temp\\CALTempTables.txt' `\n                    -fieldFilter '50000..90000|31000000..31099999'\nCreateCALTempDataUpgradeCodeunit 'C:\\Temp\\TempDataMigrationCodeunit.txt' `\n                              -fieldFilter '50000..90000|31000000..31099999'\nCreateALDataUpgradeCodeunit 'C:\\Temp\\ALDataUpgradeCodeunit.al' `\n                            -fieldFilter '50000..90000|31000000..31099999' <\/pre>\n\n\n\n<p>This is the demo script file to exemplify how to use the functions I\u2019ve created. In this example I&#8217;m filtering fields range 50000 to 90000 (custom fields &#8211; just for demo purposes because I&#8217;ve got none in the objects used) and 31000000 to 31099999 (the portuguese localization fields range).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Output<\/h2>\n\n\n\n<p>For demo purposes I\u2019ve exported six objects as text and joined them in a single file.<br>\nIn VSCode I\u2019ve opened and run the _LoadObjects.ps1 and the DataMigrationScript.ps1 files.<\/p>\n\n\n\n<p>I\u2019ve used the same output path on every function so the script will create the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Creation of the csv file with all tables and fields processed<ul><li>A single csv file is created with all the objects and fields processed<\/li><\/ul><\/li><li>Creation of the temp tables:<ul><li>A single text file is created with all each table processed.<\/li><li>In the example I only want to export data from custom files so I\u2019ve entered a field range filter so the text file only have the table key fields and the custom fields within the range.<\/li><\/ul><\/li><li>Creation of the C\/AL data migration codeunit<ul><li>A single text file is created with the data migration codeunit, refering all the tables processed.<\/li><\/ul><\/li><li>Creation of the AL data migration codeunit<ul><li>A single .al file is created with the data migration codeunit<\/li><\/ul><\/li><\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Output files<\/h4>\n\n\n\n<p>The Objects.txt file contains the following objects:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Table 3 Payment Terms<\/li><li>Table 4 Currency<\/li><li>Table 5 Finance Charge Terms<\/li><li>Table 8 Language<\/li><li>Table 15 G\/L Account<\/li><li>Table 37 Sales Line<\/li><\/ul>\n\n\n\n<p>The files generated in the output path are the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Function <strong>CreateCALFieldsCSV<\/strong> &#8211; File output: <strong>ObjectsAnalysis.csv<\/strong><\/li><\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\"> Object Type,Object Id,Object Name,Field Id,Field Name,Field Type\n   Table,3,Payment Terms,31022914,VAT Distribution,Option\n   Table,4,Currency,31022890,Decimal Currency Text,Text30\n   Table,4,Currency,31022891,Decimal places decimal Curr.,Integer\n   Table,4,Currency,31022913,Bill Groups - Collection,Boolean\n   Table,4,Currency,31022914,Bill Groups - Discount,Boolean\n   Table,4,Currency,31022915,Payment Orders,Boolean\n   Table,5,Finance Charge Terms,31022890,Sign on Issuing,Boolean\n   Table,15,G\/L Account,31022890,Income Stmt. Bal. Acc.,Code20\n   Table,15,G\/L Account,31022891,Ignore Discounts,Boolean\n   Table,15,G\/L Account,31022892,Associate DRF Code,Boolean\n   Table,15,G\/L Account,31022895,Cash-Flow Code,Code10\n   Table,15,G\/L Account,31022896,Cash-flow Code Assoc.,Boolean\n   Table,15,G\/L Account,31022897,DRF Code,Code10\n   Table,15,G\/L Account,31022970,Transfer Account Type,Option\n   Table,15,G\/L Account,31022971,Transfer Account No.,Code20\n   Table,15,G\/L Account,31022975,Taxonomy Code,Integer\n   Table,37,Sales Line,31022890,ND %,Decimal\n   Table,37,Sales Line,31022891,ND Difference,Decimal\n   Table,37,Sales Line,31022892,Not in Vat Report,Boolean\n   Table,37,Sales Line,31022893,Pmt. Disc. Given Amount,Decimal\n   Table,37,Sales Line,31022896,Stamp Duty Code,Code10\n   Table,37,Sales Line,31022897,DRF Code,Code10\n   Table,37,Sales Line,31022898,Credit-to Doc. No.,Code20\n   Table,37,Sales Line,31022899,Credit-to Doc. Line No.,Integer\n   Table,37,Sales Line,31022970,Withholding Tax Code,Code20\n   Table,37,Sales Line,31022971,Withholding Tax %,Decimal\n   Table,37,Sales Line,31022972,Withholding Tax Account,Code20\n   Table,37,Sales Line,31022973,Withholding Tax Amount,Decimal\n   Table,37,Sales Line,31022974,Orig. Withholding Tax Amount,Decimal\n   Table,37,Sales Line,31022975,Max. Correction Amount,Decimal\n   Table,37,Sales Line,31022976,Prepayment ND %,Decimal <\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>Function <strong>CreateCALTempTables<\/strong> &#8211; File output: <strong>CALTempTables.txt<\/strong><\/li><\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\"> OBJECT Table 50000 Temp Payment Terms\n {\n   FIELDS\n   {\n     { 1;;Code;Code10 }\n     { 31022914;;VAT Distribution;Option; OptionString=First Installment,Last Installment,Proportional }\n   }\n   KEYS\n   {\n     {    ;Code; }\n   }\n }\n OBJECT Table 50001 Temp Finance Charge Terms\n {\n   FIELDS\n   {\n     { 1;;Code;Code10 }\n     { 31022890;;Sign on Issuing;Boolean }\n   }\n   KEYS\n   {\n     {    ;Code; }\n   }\n }\n OBJECT Table 50002 Temp Currency\n {\n   FIELDS\n   {\n     { 1;;Code;Code10 }\n     { 31022890;;Decimal Currency Text;Text30 }\n     { 31022891;;Decimal places decimal Curr.;Integer }\n     { 31022913;;Bill Groups - Collection;Boolean }\n     { 31022914;;Bill Groups - Discount;Boolean }\n     { 31022915;;Payment Orders;Boolean }\n   }\n   KEYS\n   {\n     {    ;Code; }\n   }\n }\n OBJECT Table 50003 Temp G\/L Account\n {\n   FIELDS\n   {\n     { 1;;No.;Code20 }\n     { 31022890;;Income Stmt. Bal. Acc.;Code20 }\n     { 31022891;;Ignore Discounts;Boolean }\n     { 31022892;;Associate DRF Code;Boolean }\n     { 31022895;;Cash-Flow Code;Code10 }\n     { 31022896;;Cash-flow Code Assoc.;Boolean }\n     { 31022897;;DRF Code;Code10 }\n     { 31022970;;Transfer Account Type;Option; OptionString= ,G\/L Account,Customer,Vendor }\n     { 31022971;;Transfer Account No.;Code20 }\n     { 31022975;;Taxonomy Code;Integer }\n   }\n   KEYS\n   {\n     {    ;No.; }\n   }\n }\n OBJECT Table 50004 Temp Sales Line\n {\n   FIELDS\n   {\n     { 1;;Document Type;Option; OptionString=Quote,Order,Invoice,Credit Memo,Blanket Order,Return Order }\n     { 3;;Document No.;Code20 }\n     { 4;;Line No.;Integer }\n     { 31022890;;ND %;Decimal }\n     { 31022891;;ND Difference;Decimal }\n     { 31022892;;Not in Vat Report;Boolean }\n     { 31022893;;Pmt. Disc. Given Amount;Decimal }\n     { 31022896;;Stamp Duty Code;Code10 }\n     { 31022897;;DRF Code;Code10 }\n     { 31022898;;Credit-to Doc. No.;Code20 }\n     { 31022899;;Credit-to Doc. Line No.;Integer }\n     { 31022970;;Withholding Tax Code;Code20 }\n     { 31022971;;Withholding Tax %;Decimal }\n     { 31022972;;Withholding Tax Account;Code20 }\n     { 31022973;;Withholding Tax Amount;Decimal }\n     { 31022974;;Orig. Withholding Tax Amount;Decimal }\n     { 31022975;;Max. Correction Amount;Decimal }\n     { 31022976;;Prepayment ND %;Decimal }\n   }\n   KEYS\n   {\n     {    ;Document Type,Document No.,Line No.; }\n   }\n }<\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>Function <strong>CreateCALTempDataUpgradeCodeunit<\/strong> &#8211; File output: <strong>TempDataMigrationCodeunit.txt<\/strong><\/li><\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">OBJECT Codeunit 50000 To Temp Tables Data Upgrade\n {\n   PROPERTIES\n   {\n     Subtype=Upgrade;\n   }\n   CODE\n   {\n     VAR\n       DataUpgradeMgt@1000 : Codeunit 9900;\n\n    <code>[TableSyncSetup]<\/code>\n    <code>PROCEDURE GetTableSyncSetupCustom@50000(VAR TableSynchSetup@1000 : Record 2000000135);<\/code>\n    <code>BEGIN<\/code>\n      <code>DataUpgradeMgt.SetTableSyncSetup(DATABASE::\"Payment Terms\",DATABASE::\"Temp Payment Terms\",TableSynchSetup.Mode::Copy);<\/code>\n      <code>DataUpgradeMgt.SetTableSyncSetup(DATABASE::\"Finance Charge Terms\",DATABASE::\"Temp Finance Charge Terms\",TableSynchSetup.Mode::Copy);<\/code>\n      <code>DataUpgradeMgt.SetTableSyncSetup(DATABASE::\"Currency\",DATABASE::\"Temp Currency\",TableSynchSetup.Mode::Copy);<\/code>\n      <code>DataUpgradeMgt.SetTableSyncSetup(DATABASE::\"G\/L Account\",DATABASE::\"Temp G\/L Account\",TableSynchSetup.Mode::Copy);<\/code>\n      <code>DataUpgradeMgt.SetTableSyncSetup(DATABASE::\"Sales Line\",DATABASE::\"Temp Sales Line\",TableSynchSetup.Mode::Copy);<\/code>\n    <code>END;<\/code>\n\n    <code>BEGIN<\/code>\n    <code>END.<\/code>\n  }\n}<\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>Function <strong>CreateALDataUpgradeCodeunit<\/strong> &#8211; File output: <strong>ALDataUpgradeCodeunit.al<\/strong><\/li><\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">codeunit 50100 \"Data Upgrade Codeunit\"\n {\n   Subtype = Upgrade;\n trigger OnRun()\n   begin\n   end;\n local procedure Payment_Terms()\n   var\n     DestinyTable: Record \"Payment Terms\";\n     OriginTable: Record \"Temp Payment Terms\";\n   begin\n     With OriginTable do begin\n       if FindSet() then\n       repeat\n         DestinyTable.Init();\n         DestinyTable.\"VAT Distribution\" := OriginTable.\"VAT Distribution\";\n         DestinyTable.Insert;\n       until next = 0;\n       \/\/DeleteAll();\n     end;\n   end;\n local procedure Finance_Charge_Terms()\n   var\n     DestinyTable: Record \"Finance Charge Terms\";\n     OriginTable: Record \"Temp Finance Charge Terms\";\n   begin\n     With OriginTable do begin\n       if FindSet() then\n       repeat\n         DestinyTable.Init();\n         DestinyTable.\"Sign on Issuing\" := OriginTable.\"Sign on Issuing\";\n         DestinyTable.Insert;\n       until next = 0;\n       \/\/DeleteAll();\n     end;\n   end;\n local procedure Currency()\n   var\n     DestinyTable: Record \"Currency\";\n     OriginTable: Record \"Temp Currency\";\n   begin\n     With OriginTable do begin\n       if FindSet() then\n       repeat\n         DestinyTable.Init();\n         DestinyTable.\"Decimal Currency Text\" := OriginTable.\"Decimal Currency Text\";\n         DestinyTable.\"Decimal places decimal Curr.\" := OriginTable.\"Decimal places decimal Curr.\";\n         DestinyTable.\"Bill Groups - Collection\" := OriginTable.\"Bill Groups - Collection\";\n         DestinyTable.\"Bill Groups - Discount\" := OriginTable.\"Bill Groups - Discount\";\n         DestinyTable.\"Payment Orders\" := OriginTable.\"Payment Orders\";\n         DestinyTable.Insert;\n       until next = 0;\n       \/\/DeleteAll();\n     end;\n   end;\n local procedure G\/L_Account()\n   var\n     DestinyTable: Record \"G\/L Account\";\n     OriginTable: Record \"Temp G\/L Account\";\n   begin\n     With OriginTable do begin\n       if FindSet() then\n       repeat\n         DestinyTable.Init();\n         DestinyTable.\"Income Stmt. Bal. Acc.\" := OriginTable.\"Income Stmt. Bal. Acc.\";\n         DestinyTable.\"Ignore Discounts\" := OriginTable.\"Ignore Discounts\";\n         DestinyTable.\"Associate DRF Code\" := OriginTable.\"Associate DRF Code\";\n         DestinyTable.\"Cash-Flow Code\" := OriginTable.\"Cash-Flow Code\";\n         DestinyTable.\"Cash-flow Code Assoc.\" := OriginTable.\"Cash-flow Code Assoc.\";\n         DestinyTable.\"DRF Code\" := OriginTable.\"DRF Code\";\n         DestinyTable.\"Transfer Account Type\" := OriginTable.\"Transfer Account Type\";\n         DestinyTable.\"Transfer Account No.\" := OriginTable.\"Transfer Account No.\";\n         DestinyTable.\"Taxonomy Code\" := OriginTable.\"Taxonomy Code\";\n         DestinyTable.Insert;\n       until next = 0;\n       \/\/DeleteAll();\n     end;\n   end;\n local procedure Sales_Line()\n   var\n     DestinyTable: Record \"Sales Line\";\n     OriginTable: Record \"Temp Sales Line\";\n   begin\n     With OriginTable do begin\n       if FindSet() then\n       repeat\n         DestinyTable.Init();\n         DestinyTable.\"ND %\" := OriginTable.\"ND %\";\n         DestinyTable.\"ND Difference\" := OriginTable.\"ND Difference\";\n         DestinyTable.\"Not in Vat Report\" := OriginTable.\"Not in Vat Report\";\n         DestinyTable.\"Pmt. Disc. Given Amount\" := OriginTable.\"Pmt. Disc. Given Amount\";\n         DestinyTable.\"Stamp Duty Code\" := OriginTable.\"Stamp Duty Code\";\n         DestinyTable.\"DRF Code\" := OriginTable.\"DRF Code\";\n         DestinyTable.\"Credit-to Doc. No.\" := OriginTable.\"Credit-to Doc. No.\";\n         DestinyTable.\"Credit-to Doc. Line No.\" := OriginTable.\"Credit-to Doc. Line No.\";\n         DestinyTable.\"Withholding Tax Code\" := OriginTable.\"Withholding Tax Code\";\n         DestinyTable.\"Withholding Tax %\" := OriginTable.\"Withholding Tax %\";\n         DestinyTable.\"Withholding Tax Account\" := OriginTable.\"Withholding Tax Account\";\n         DestinyTable.\"Withholding Tax Amount\" := OriginTable.\"Withholding Tax Amount\";\n         DestinyTable.\"Orig. Withholding Tax Amount\" := OriginTable.\"Orig. Withholding Tax Amount\";\n         DestinyTable.\"Max. Correction Amount\" := OriginTable.\"Max. Correction Amount\";\n         DestinyTable.\"Prepayment ND %\" := OriginTable.\"Prepayment ND %\";\n         DestinyTable.Insert;\n       until next = 0;\n       \/\/DeleteAll();\n     end;\n   end;\n trigger OnUpgradePerCompany()\n   begin\n     Payment_Terms;\n     Finance_Charge_Terms;\n     Currency;\n     G\/L_Account;\n     Sales_Line;\n   end;\n }<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Considerations<\/h2>\n\n\n\n<ul class=\"wp-block-list\"><li><s>Actually the filtering only works for fields. For example, if you apply the filter &#8216;50000..59999&#8217; and you have a custom table with id 50000 and field no. 1, 2, 3, etc., this script won&#8217;t process it because the fields are not within the range.<\/s><\/li><li><s>Adding a parameter to filter tables instead it straight forward but I didn&#8217;t do that in this version;<\/s><\/li><li><strong>UPDATE 2020\/03\/29:<\/strong> It is now possible to filter tables and\/or fields;<\/li><li>Processing a NAV 2017 full objects file took around 20 minutes (5 minutes for each function). This could be optimized if I combine all functionalities in the same function so that tables and fields are only enumerated once.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Final Words<\/h2>\n\n\n\n<p>I hope you find this script useful. Please leave your comments and let me know if there&#8217;s something that can be improved. If you find any error, please let me know as well.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Eric Walters (Waldo) shared a great tool developed \u201con top of\u201d the existing Microsoft.Dynamics.Nav.Model.Tools.dll, which is a library that serves the PowerShell Merge-CmdLets provided by Microsoft, that allow us to do a bunch of analysis on top of NAV\/BC objects (man, you rock!). More info here: https:\/\/www.waldo.be\/2019\/02\/15\/c-al-source-code-analysis-with-powershell\/ And here: https:\/\/github.com\/waldo1001\/Waldo.Model.Tools I have created a script [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1358,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[4],"tags":[59,6],"class_list":{"0":"post-1763","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","6":"hentry","7":"category-dynamics365bc","8":"tag-businesscentral","9":"tag-dynamicsnav-2","11":"post-with-thumbnail","12":"post-with-thumbnail-icon"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>C\/AL to AL Data Upgrade Automation Powershell Script - Ricardo Paiva Moinhos<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/\" \/>\n<meta property=\"og:locale\" content=\"pt_PT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"C\/AL to AL Data Upgrade Automation Powershell Script - Ricardo Paiva Moinhos\" \/>\n<meta property=\"og:description\" content=\"Eric Walters (Waldo) shared a great tool developed \u201con top of\u201d the existing Microsoft.Dynamics.Nav.Model.Tools.dll, which is a library that serves the PowerShell Merge-CmdLets provided by Microsoft, that allow us to do a bunch of analysis on top of NAV\/BC objects (man, you rock!). More info here: https:\/\/www.waldo.be\/2019\/02\/15\/c-al-source-code-analysis-with-powershell\/ And here: https:\/\/github.com\/waldo1001\/Waldo.Model.Tools I have created a script [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/\" \/>\n<meta property=\"og:site_name\" content=\"Ricardo Paiva Moinhos\" \/>\n<meta property=\"article:published_time\" content=\"2020-03-12T22:57:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-03-29T00:53:44+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/ricardomoinhos.com\/wp-content\/uploads\/2020\/02\/Microsoft-Dynamics-365-Business-Central-Logo.png\" \/>\n\t<meta property=\"og:image:width\" content=\"256\" \/>\n\t<meta property=\"og:image:height\" content=\"256\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Ricardo Paiva Moinhos\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Ricardo Paiva Moinhos\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tempo estimado de leitura\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/ricardomoinhos.com\\\/c-al-to-al-data-upgrade-automation-powershell-script\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ricardomoinhos.com\\\/c-al-to-al-data-upgrade-automation-powershell-script\\\/\"},\"author\":{\"name\":\"Ricardo Paiva Moinhos\",\"@id\":\"https:\\\/\\\/ricardomoinhos.com\\\/#\\\/schema\\\/person\\\/16dcfdd54ec1c46bd1941659739de4cc\"},\"headline\":\"C\\\/AL to AL Data Upgrade Automation Powershell Script\",\"datePublished\":\"2020-03-12T22:57:00+00:00\",\"dateModified\":\"2020-03-29T00:53:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/ricardomoinhos.com\\\/c-al-to-al-data-upgrade-automation-powershell-script\\\/\"},\"wordCount\":863,\"commentCount\":3,\"image\":{\"@id\":\"https:\\\/\\\/ricardomoinhos.com\\\/c-al-to-al-data-upgrade-automation-powershell-script\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ricardomoinhos.com\\\/wp-content\\\/uploads\\\/2020\\\/02\\\/Microsoft-Dynamics-365-Business-Central-Logo.png\",\"keywords\":[\"\",\"dynamicsnav\"],\"articleSection\":[\"Dynamics NAV\\\/365 BC\"],\"inLanguage\":\"pt-PT\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/ricardomoinhos.com\\\/c-al-to-al-data-upgrade-automation-powershell-script\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/ricardomoinhos.com\\\/c-al-to-al-data-upgrade-automation-powershell-script\\\/\",\"url\":\"https:\\\/\\\/ricardomoinhos.com\\\/c-al-to-al-data-upgrade-automation-powershell-script\\\/\",\"name\":\"C\\\/AL to AL Data Upgrade Automation Powershell Script - Ricardo Paiva Moinhos\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/ricardomoinhos.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/ricardomoinhos.com\\\/c-al-to-al-data-upgrade-automation-powershell-script\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/ricardomoinhos.com\\\/c-al-to-al-data-upgrade-automation-powershell-script\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/ricardomoinhos.com\\\/wp-content\\\/uploads\\\/2020\\\/02\\\/Microsoft-Dynamics-365-Business-Central-Logo.png\",\"datePublished\":\"2020-03-12T22:57:00+00:00\",\"dateModified\":\"2020-03-29T00:53:44+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/ricardomoinhos.com\\\/#\\\/schema\\\/person\\\/16dcfdd54ec1c46bd1941659739de4cc\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/ricardomoinhos.com\\\/c-al-to-al-data-upgrade-automation-powershell-script\\\/#breadcrumb\"},\"inLanguage\":\"pt-PT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/ricardomoinhos.com\\\/c-al-to-al-data-upgrade-automation-powershell-script\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-PT\",\"@id\":\"https:\\\/\\\/ricardomoinhos.com\\\/c-al-to-al-data-upgrade-automation-powershell-script\\\/#primaryimage\",\"url\":\"https:\\\/\\\/ricardomoinhos.com\\\/wp-content\\\/uploads\\\/2020\\\/02\\\/Microsoft-Dynamics-365-Business-Central-Logo.png\",\"contentUrl\":\"https:\\\/\\\/ricardomoinhos.com\\\/wp-content\\\/uploads\\\/2020\\\/02\\\/Microsoft-Dynamics-365-Business-Central-Logo.png\",\"width\":256,\"height\":256},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/ricardomoinhos.com\\\/c-al-to-al-data-upgrade-automation-powershell-script\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/ricardomoinhos.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"C\\\/AL to AL Data Upgrade Automation Powershell Script\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/ricardomoinhos.com\\\/#website\",\"url\":\"https:\\\/\\\/ricardomoinhos.com\\\/\",\"name\":\"Ricardo Paiva Moinhos\",\"description\":\"Welcome\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/ricardomoinhos.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-PT\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/ricardomoinhos.com\\\/#\\\/schema\\\/person\\\/16dcfdd54ec1c46bd1941659739de4cc\",\"name\":\"Ricardo Paiva Moinhos\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-PT\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/248366f4e615e182964f85f799c6e33cbd541a6f4ca7ee948fc16d1c14030c76?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/248366f4e615e182964f85f799c6e33cbd541a6f4ca7ee948fc16d1c14030c76?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/248366f4e615e182964f85f799c6e33cbd541a6f4ca7ee948fc16d1c14030c76?s=96&d=mm&r=g\",\"caption\":\"Ricardo Paiva Moinhos\"},\"url\":\"https:\\\/\\\/ricardomoinhos.com\\\/pt\\\/author\\\/ricardopaiva\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"C\/AL to AL Data Upgrade Automation Powershell Script - Ricardo Paiva Moinhos","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/","og_locale":"pt_PT","og_type":"article","og_title":"C\/AL to AL Data Upgrade Automation Powershell Script - Ricardo Paiva Moinhos","og_description":"Eric Walters (Waldo) shared a great tool developed \u201con top of\u201d the existing Microsoft.Dynamics.Nav.Model.Tools.dll, which is a library that serves the PowerShell Merge-CmdLets provided by Microsoft, that allow us to do a bunch of analysis on top of NAV\/BC objects (man, you rock!). More info here: https:\/\/www.waldo.be\/2019\/02\/15\/c-al-source-code-analysis-with-powershell\/ And here: https:\/\/github.com\/waldo1001\/Waldo.Model.Tools I have created a script [&hellip;]","og_url":"https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/","og_site_name":"Ricardo Paiva Moinhos","article_published_time":"2020-03-12T22:57:00+00:00","article_modified_time":"2020-03-29T00:53:44+00:00","og_image":[{"width":256,"height":256,"url":"https:\/\/ricardomoinhos.com\/wp-content\/uploads\/2020\/02\/Microsoft-Dynamics-365-Business-Central-Logo.png","type":"image\/png"}],"author":"Ricardo Paiva Moinhos","twitter_card":"summary_large_image","twitter_misc":{"Escrito por":"Ricardo Paiva Moinhos","Tempo estimado de leitura":"10 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/#article","isPartOf":{"@id":"https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/"},"author":{"name":"Ricardo Paiva Moinhos","@id":"https:\/\/ricardomoinhos.com\/#\/schema\/person\/16dcfdd54ec1c46bd1941659739de4cc"},"headline":"C\/AL to AL Data Upgrade Automation Powershell Script","datePublished":"2020-03-12T22:57:00+00:00","dateModified":"2020-03-29T00:53:44+00:00","mainEntityOfPage":{"@id":"https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/"},"wordCount":863,"commentCount":3,"image":{"@id":"https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/#primaryimage"},"thumbnailUrl":"https:\/\/ricardomoinhos.com\/wp-content\/uploads\/2020\/02\/Microsoft-Dynamics-365-Business-Central-Logo.png","keywords":["","dynamicsnav"],"articleSection":["Dynamics NAV\/365 BC"],"inLanguage":"pt-PT","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/","url":"https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/","name":"C\/AL to AL Data Upgrade Automation Powershell Script - Ricardo Paiva Moinhos","isPartOf":{"@id":"https:\/\/ricardomoinhos.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/#primaryimage"},"image":{"@id":"https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/#primaryimage"},"thumbnailUrl":"https:\/\/ricardomoinhos.com\/wp-content\/uploads\/2020\/02\/Microsoft-Dynamics-365-Business-Central-Logo.png","datePublished":"2020-03-12T22:57:00+00:00","dateModified":"2020-03-29T00:53:44+00:00","author":{"@id":"https:\/\/ricardomoinhos.com\/#\/schema\/person\/16dcfdd54ec1c46bd1941659739de4cc"},"breadcrumb":{"@id":"https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/#breadcrumb"},"inLanguage":"pt-PT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/"]}]},{"@type":"ImageObject","inLanguage":"pt-PT","@id":"https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/#primaryimage","url":"https:\/\/ricardomoinhos.com\/wp-content\/uploads\/2020\/02\/Microsoft-Dynamics-365-Business-Central-Logo.png","contentUrl":"https:\/\/ricardomoinhos.com\/wp-content\/uploads\/2020\/02\/Microsoft-Dynamics-365-Business-Central-Logo.png","width":256,"height":256},{"@type":"BreadcrumbList","@id":"https:\/\/ricardomoinhos.com\/c-al-to-al-data-upgrade-automation-powershell-script\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/ricardomoinhos.com\/"},{"@type":"ListItem","position":2,"name":"C\/AL to AL Data Upgrade Automation Powershell Script"}]},{"@type":"WebSite","@id":"https:\/\/ricardomoinhos.com\/#website","url":"https:\/\/ricardomoinhos.com\/","name":"Ricardo Paiva Moinhos","description":"Welcome","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/ricardomoinhos.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-PT"},{"@type":"Person","@id":"https:\/\/ricardomoinhos.com\/#\/schema\/person\/16dcfdd54ec1c46bd1941659739de4cc","name":"Ricardo Paiva Moinhos","image":{"@type":"ImageObject","inLanguage":"pt-PT","@id":"https:\/\/secure.gravatar.com\/avatar\/248366f4e615e182964f85f799c6e33cbd541a6f4ca7ee948fc16d1c14030c76?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/248366f4e615e182964f85f799c6e33cbd541a6f4ca7ee948fc16d1c14030c76?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/248366f4e615e182964f85f799c6e33cbd541a6f4ca7ee948fc16d1c14030c76?s=96&d=mm&r=g","caption":"Ricardo Paiva Moinhos"},"url":"https:\/\/ricardomoinhos.com\/pt\/author\/ricardopaiva\/"}]}},"jetpack_featured_media_url":"https:\/\/ricardomoinhos.com\/wp-content\/uploads\/2020\/02\/Microsoft-Dynamics-365-Business-Central-Logo.png","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ricardomoinhos.com\/pt\/wp-json\/wp\/v2\/posts\/1763","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ricardomoinhos.com\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ricardomoinhos.com\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ricardomoinhos.com\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ricardomoinhos.com\/pt\/wp-json\/wp\/v2\/comments?post=1763"}],"version-history":[{"count":4,"href":"https:\/\/ricardomoinhos.com\/pt\/wp-json\/wp\/v2\/posts\/1763\/revisions"}],"predecessor-version":[{"id":1905,"href":"https:\/\/ricardomoinhos.com\/pt\/wp-json\/wp\/v2\/posts\/1763\/revisions\/1905"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ricardomoinhos.com\/pt\/wp-json\/wp\/v2\/media\/1358"}],"wp:attachment":[{"href":"https:\/\/ricardomoinhos.com\/pt\/wp-json\/wp\/v2\/media?parent=1763"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ricardomoinhos.com\/pt\/wp-json\/wp\/v2\/categories?post=1763"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ricardomoinhos.com\/pt\/wp-json\/wp\/v2\/tags?post=1763"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}