By Steve Endow
On January 23, 2021, I recorded a video showing how to create a simple text file using AL in Business Central.
Here is the video:
https://www.youtube.com/watch?v=_GUzlFKJFQk
Below is the sample code from that video.
Steve Endow is a Microsoft MVP who works with Microsoft Dynamics 365 Business Central, Power Apps, Power Automate, Azure, .NET, and SQL Server
Dynamics 365 BC Resources List: https://bit.ly/bcresources
By Steve Endow
On January 23, 2021, I recorded a video showing how to create a simple text file using AL in Business Central.
Here is the video:
https://www.youtube.com/watch?v=_GUzlFKJFQk
Below is the sample code from that video.
By Steve Endow
If you are creating Business Central Docker Containers and regularly updating the artifacts and images for your containers, you may be familiar with this problem.
When you type "docker images" in PowerShell, you are greeted with a pile of old unused images consuming tons of disk space.
![]() |
A digital junk drawer |
I want to delete the old, unused Docker images. But I do not want to delete the 10.4 GB "base OS" image that is listed at the very bottom. As long as my OS version remains the same, that image can be used repeatedly, and if I deleted it, I would have to download it again.
By Steve Endow
While using Business Central with Google Chrome, I started to notice strange words appearing in Business Central fields while I entered data in the browser.
![]() |
Why are you doing this? |
In this example, the word "test" was appearing when I clicked on the drop down list for bank accounts in Business Central. The suggested value was in a text box displayed over the standard Business Central list box.
By Steve Endow
Update: I originally wrote this post referencing my Lenovo ThinkPad P1 laptop, but it appears that similar Intel Graphics software is used on several different laptop brands and models, causing the same issue. The name or appearance of the specific Intel Graphics software may vary, but the concept still applies.
If you use Dynamics 365 Business Central, you should be aware of the Page Inspection feature.
![]() |
Inspect my page |
https://docs.microsoft.com/en-us/dynamics365/business-central/across-inspect-page
One of the ways to open the Page Inspection pane while viewing a Business Central page in a browser is to press the keyboard shortcut CTRL + ALT + F1.
![]() |
Handy Keyboard Shorcut |
While doing some BC development and testing on my new Lenovo ThinkPad P1 laptop, I pressed CTRL + ALT + F1 to open Page Inspection.
But nothing happened.
By Steve Endow
The Business Central Community is amazing.
Want proof?
Here's a great example from my Twitter timeline this afternoon:
https://twitter.com/steveendow/status/1306667765369991168?s=20
![]() |
This is Community |
"Business Central Twitter" is in constant conversation. Business Central community members from around the globe, quite literally, are asking questions, answering questions, posting updates, blogs, videos, and MS Docs articles.
By Steve Endow
Do you know how I access Business Central?
I pull up my web browser, and I click a shortcut on the browser shortcut bar.
![]() |
Single click |
And you probably know what I see next.
![]() |
I've arrived |
A glorious, modern, rich, interactive, attractive, customizable user interface. Take a moment to appreciate this significant feature of Business Central.
A "native" web interface. A native web application. Pretty amazing.
I didn't have to install an application on my computer. I didn't have to configure anything on my computer. I didn't have to setup a web server or install a web client. In fact, I can access Business Central from any computer. I just need a web browser. Or I can install the Business Central mobile application.
By Steve Endow
"What? Are you crazy, Steve? Not having access to SQL is a limitation! It's a weakness! That's not amazing!"
I am not trying to change anyone else's mind--I'm just sharing a few thoughts why I think that NOT having access to SQL Server is amazing.
I've been working with on-prem ERP systems since 1996, when I implemented Solomon IV for Windows, then MAS 90, then Peoplesoft, then Dynamics GP. I'm aware of all the arguments for wanting or needing access to SQL. I get it.
But that direct access comes at significant cost. And responsibility. And risk. And those things are not amazing. Mid-market companies want to sell their product or service, to provide customer satisfaction, and to make revenue.
They don't want to be in the ERP database administration business. Or the ERP database backup business. Or the ERP disaster recovery business. Or the ransomware defense business.
![]() |
Do you really want to be in the database administration and maintenance business? |
By Steve Endow
After seeing a few very cool Business Central features the other day, I was so impressed and in such a good mood that I might have posted a slightly overly enthusiastic tweet.
![]() |
Can't a guy be in a really good mood? |
Does Business Central do my dishes? My laundry? Paint my house?
Sadly, it does not. Yet. 😉
But it does do lots of awesome things and it has some amazing features and benefits. And after posting my happy tweet, I think a few people are wondering why I think Business Central is so amazing.
So now I feel obligated to explain why I think it's amazing, and in the process, share my enthusiasm for the new ERP platform that I'm learning about.
By Steve Endow
UPDATE: If you're interested in a convenient way to run the BcContainerHelper PowerShell commands, check out Krzysztof's Azure Data Studio Notebook with sample BcContainerHelper commands. Jupyter Notebooks are a great way to include documentation and commands in a single convenient format.
On August 11, 2020, Freddy Kristiansen announced that he had released BcContainerHelper.
You can read his blog post here:
https://freddysblog.com/2020/08/11/bccontainerhelper/
You will definitely want to read the entire blog post carefully, and perhaps read it a few times, as he shares quite a few important details about the new BcContainerHelper.
![]() |
Same Great Container Helper, But Updated and Upgraded! |
I made a video showing how I updated from NavContainerHelper to BcContainerHelper. The process went flawlessly.
Here are the PowerShell Docker commands that I used to perform my update.
![]() |
No soup for you! |
![]() |
Email notification when an update occurs |
#v1.0 - March 27, 2021
#
$server = $env:COMPUTERNAME
#Define date values
$simpleDate = Get-Date -Format "M/d/yy"
$dateTime = Get-Date -Format "M/d/yy HH:mm"
$fileDateTime = Get-Date -Format "yyyy-MM-dd HHmm"
#Define the module name
$moduleName = 'BcContainerHelper'
$body = ""
$message = ""
$updated = $false
#Specify file location for activity transcript log file
$transcriptFile = "D:\BCPowerShell\Logs\" + $fileDateTime + " " + $server + " " + $moduleName + " Update Log.txt"
#Start recording transcript
Start-Transcript -Path $transcriptFile
#Record the start time
$StartTime = $(get-date)
#Define email configuration
$emailFrom = "myemail@gmail.com"
$emailTo = "myemail@gmail.com"
$smtpServer = "smtp.gmail.com"
$port = "587"
#Email password file created using: Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File -FilePath D:\BCPowerShell\Gmail_password.securestring
$passwordFile = "D:\BCPowerShell\Gmail_password.securestring"
$securePassword = ConvertTo-SecureString (Get-Content -Path $passwordFile)
$smtpCred = New-Object -TypeName PSCredential ($emailFrom, $securePassword)
$subject = $server + ": " + $simpleDate + " " + $moduleName + " Update Log";
$started = "Start time: " + $StartTime
$body += $started + "`n`n"
Try
{
#Get currently installed version
$currentVersion = (Get-InstalledModule $moduleName -ErrorAction SilentlyContinue).Version.ToString()
}
Catch
{
$currentVersion = "(not installed)"
}
#Get the latest version available
$latestVersion = (Find-Module $moduleName).Version.ToString()
#If we don't have the latest version installed
If ($currentVersion -ne $latestVersion)
{
$message = "Current version: " + $currentVersion + "`nLatest version: " + $latestVersion;
$message += "`n`nUpdating to version " + $latestVersion;
#Remove existing version(s)
Uninstall-Module $moduleName -Force -AllVersions -ErrorAction SilentlyContinue
#Install latest version
Install-Module $moduleName -Force
$updated = $true;
#Verify version number
$currentVersion = (Get-InstalledModule $moduleName).Version.ToString()
$message += "`nUpdate complete";
$message += "`nCurrent version is now " + $currentVersion;
$body += "`n" + $message;
Write-Output $message
}
Else
{
#If we are on the latest version, log that info
$message = "You are on the latest version of " + $moduleName + ": " + $currentVersion;
Write-Output $message
}
#Record end time
$EndTime = $(get-date)
$output = "`nEnd time: " + $EndTime
$body += "`n" + $output
Write-Output $output
#Calculate elapsed time
$elapsedTime = $EndTime - $StartTime
$totalTime = "{0:HH:mm:ss}" -f ([datetime]$elapsedTime.Ticks)
$output = "Elapsed time: " + $totalTime
$body += "`n" + $output
Write-Output $output
$body += "`n`nFull log file is attached"
#Finish the transcript recording
#The Transcript must be stopped before trying to send the email,
#otherwise the log file will be locked, causing the email to fail
Stop-Transcript
if ($updated)
{
#Send the email
Send-MailMessage -From $emailFrom -To $emailTo `
-Subject $subject `
-Body $body `
-Attachments $transcriptFile `
-SmtpServer $smtpServer `
-Credential $smtpCred `
-Port $port `
-UseSsl
}
![]() |
Just tell me how it went... |
![]() |
Ya gotta measure things |
$StartTime = $(get-date)
Try {
$output = "Started: " + $StartTime
Write-Output $output
$containerName = 'bc1'
$password = 'P@ssw0rd'
$securePassword = ConvertTo-SecureString -String $password -AsPlainText -Force
$credential = New-Object pscredential 'admin', $securePassword
$auth = 'UserPassword'
$artifactUrl = Get-BcArtifactUrl -type 'Sandbox' -version '' -country 'us' -select 'Latest'
New-BcContainer `
-accept_eula `
-containerName $containerName `
-credential $credential `
-auth $auth `
-artifactUrl $artifactUrl `
-imageName 'myimage1' `
-dns '8.8.8.8' `
-updateHosts
}
Catch {
Write-Error "Um, something didn't go well:"
Write-Error $_
}
Finally {
$EndTime = $(get-date)
$output = "End time: " + $EndTime
Write-Output $output
$elapsedTime = $(get-date) - $StartTime
$totalTime = "{0:HH:mm:ss}" -f ([datetime]$elapsedTime.Ticks)
$output = "Elapsed time: " + $totalTime
Write-Output $output
}
![]() |
Building a new named image vs. using an existing named image |
$MyModuleName = 'NavContainerHelper'
Uninstall-Module $MyModuleName -Force -AllVersions
Install-Module $MyModuleName -Force
![]() |
The Script |
![]() |
Windows Task Scheduler |
![]() |
Task - General Info |
![]() |
Nightly update |
![]() |
PowerShell isn't too bad |
Open Powershell / Powershell ISE on HOST machine using Run As Administrator
NOTE: When referring to a Container ID or Image ID, you can use the first
few characters of the ID if they are unique--you do not have to always
use the full ID.
Check NavContainerHelper Version
Get-InstalledModule NavContainerHelper
Fresh Install of NavContainerHelper
Install-module navcontainerhelper
Import-Module navcontainerhelper
Install Latest NavContainerHelper
If you KNOW you don't have multiple versions installed:
Update-Module NavContainerHelper -Force
If you MIGHT have multiple versions installed:
$MyModuleName = <modulename>
Uninstall-Module $MyModuleName -allversions
Install-Module $MyModuleName
NOTE: I do not recommend using the -Force option with Install-Module.
It can bypass valuable warnings that you want to know about.
Alternate method to Remove Old Versions of NavContainerHelper
$ModuleName = 'navcontainerhelper';
$Latest = Get-InstalledModule $ModuleName;
Get-InstalledModule $ModuleName -AllVersions | ? {$_.Version -ne $Latest.Version} | Uninstall-Module -WhatIf
Container Management Commands
Compact Container listing:
docker ps --format "table {{.Names}}\t{{.ID}}\t{{.CreatedAt}}\t{{.Status}}"
Full listing:
docker ps
docker ps -a
docker start <id>
docker stop <id>
docker container inspect
Remove Container
Recommended method:
Remove-BCContainer <containername>
Manual Docker method:
docker stop <id>
docker rm <id>
Manually clean up hosts file
Manually remove desktop icons
Manually remove extensions from C:\ProgramData\NavContainerHelper\Extensions\
Stop all running containers:
docker stop $(docker ps -aq)
Images
docker images
docker images -a
Remove Image
docker rmi <id>
docker rmi <repository>:<tag>
Remove all images:
docker rmi $(docker images -aq)
Clean up old images
Remove orphaned images with "< none >" identifiers:
docker images -q -f dangling=true | % { docker rmi $_ }
Remove orphaned images:
docker image prune -f
Remove orphaned AND UNUSED images:
WARNING: Be careful with this: It will remove generic OS images used by NavContainerHelper!
docker image prune -a -f
Get Artifact Info for an existing BC Container:
Get-BcContainerArtifactUrl containername
Get-NavContainerArtifactUrl containername
Diagnostics
Get-BcContainerEventLog
Create New BC Container
New-BcContainerWizard
https://blog.baudson.de/blog/stop-and-remove-all-docker-containers-and-images
$containerName = 'sandbox1'
$password = 'P@ssword'
$securePassword = ConvertTo-SecureString -String $password -AsPlainText -Force
$credential = New-Object pscredential 'admin', $securePassword
$auth = 'UserPassword'
$artifactUrl = Get-BcArtifactUrl -type 'Sandbox' -version '' -country 'us' -select 'Latest'
$licenseFile = 'c:\zdisks\business central\2020-06bcv16license.flf'
New-BcContainer `
-accept_eula `
-containerName $containerName `
-credential $credential `
-auth $auth `
-artifactUrl $artifactUrl `
-updateHosts `
-assignPremiumPlan `
-licenseFile $licenseFile `
-dns '192.168.25.21' `
-imageName 'mybc16'
Setup-BcContainerTestUsers -containerName $containerName -Password $credential.Password -credential $credential
![]() |
Sad Trombone |
![]() |
The last few digits are the important ones |
![]() |
I'm talkin' to you! |
![]() |
Install-Module -Force Warning |
#Containers
docker ps
docker ps -a
docker start <id>
docker stop <id>
docker rm <id>
#Stop all running containers:
docker stop $(docker ps -aq)
#Images
docker images
docker images -a
docker rmi <id>
docker rmi <repository>:<tag>
#Check NavContainerHelper version
Get-InstalledModule
#Install Latest NavContainerHelper
$MyModuleName = <modulename>
Uninstall-Module $MyModuleName -allversions
Install-Module $MyModuleName -Force
By Steve Endow In the software / consulting world, we're sometimes given data that is messy, and we, the software developers, consultan...