Monday, August 17, 2020

Why Business Central Is Amazing #1 - Automatic Upgrades

 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.

Saturday, August 15, 2020

Updating from NavContainerHelper to the new BcContainerHelper

 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.

Sunday, August 9, 2020

Learning Business Central Development from Scratch Video Series

By Steve Endow

If you are new to Dynamics 365 Business Central development, join me on a journey to learn how to develop Business Central Extensions using VS Code and the AL language.

I have been developing business software for many, many years, but I am completely new to Business Central, AL, and VS Code.  And I am also new to Docker and PowerShell.  

Basically, I'm having to learn everything from scratch.  

I'm writing blog posts and making videos to share the learning resources I'm using and share my learning journey.

Tuesday, August 4, 2020

Business Central Download Symbols Error: No such host is known

By Steve Endow


UPDATE:  After researching this type of Windows hosts file name resolution issue, it seems there are dozens of possible reasons why the problem can occur.  I suspect my case was one of the simpler versions, and fortunately flushdns worked for me.  Here is a forum thread with examples of several rather odd causes and solutions.


This morning I tried to create a new Business Central AL project in VS Code.  I used AL Go! to create the project, set the server name in the launch.json file, and then tried to Download Symbols.

Very simple, very easy, right?

Nope.

No soup for you!

What? I performed these exact same steps 2 days ago on this same machine, and I was able to download symbols without any issues.

Here is the full video of the troubleshooting process:




I closed VS Code, relaunched it, created a new project, and tried again.  Same error.

Looking at the error log in VS Code, I saw "Error: No such host is known".  Say what?

Monday, August 3, 2020

Automatically Update BcContainerHelper - Improved Script

By Steve Endow

UPDATE: I have updated the script to work with the newer BcContainerHelper rather than the older NavContainerHelper


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.


I previously wrote about creating a simple scheduled task to automatically update NavContainerHelper.

While that simple script does work, it didn't have any logging or notification. I never knew when NavContainerHelper / BcContainerHelper was updated.

I recently created a fancier PowerShell script to automatically build my Business Central Docker Containers every day, and while working on that script, I learned how to record elapsed time, log all activity, and send an email notification.

Based on that new learning, I wanted to upgrade the script that updates BcContainerHelper.

I wanted logging, elapsed time, and email notification if BcContainerHelper was updated to a new version.

Email notification when an update occurs


Here's what I came up with.  You'll need to adjust the file paths and email address, and generate your own email password file.

If you think of any other features the update could have, let me know!

 #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
}  


Steve Endow is a Microsoft MVP in Los Angeles.  He works with Dynamics 365 Business Central, Microsoft Power Automate, Power Apps, Azure, .NET, Dynamics GP, and SQL Server.

You can also find him on Twitter and YouTube

https://www.precipioservices.com

Saturday, July 25, 2020

Fully automate the Business Central Container build process

By Steve Endow

I don't like maintenance tasks.  I don't like having to remember to do something on a regular basis.  I don't like having to do low value tasks constantly.

While it has been valuable for me to manually run NavContainerHelper the last several months, I think I am finally at a point where I sufficiently understand how it works and what it does.  I'm now ready to automate my Business Central Container build process so that I don't have to do it manually.

Just tell me how it went...

This isn't anything new--I'm just finally getting around to doing it for me with the features that I want.  If there are other ways or better ways to do this, let me know.

I share the background, my thinking, and my journey creating the script in this video.



In short, I've just wrapped the call to New-BcContainer in some additional PowerShell script to enable full logging, some basic error handling, and email notification.

Friday, July 24, 2020

Recording Business Central NavContainerHelper benchmarks

By Steve Endow

As I've been using NavContainerHelper, it's become clear that there can be a lot of waiting as it downloads gigabytes of data for the images and hundreds of megabytes for the artifacts.  It then has to mash all of that together to build a Business Central Container.  It can take a while.

Sometimes it seems the process is pretty quick.  But sometimes the process seems to take forever.  When it's in the middle of doing its thing, I can't tell whether it's taking longer than normal, or if it just feels like it's taking a long time.

So I'm now measuring how long it takes for NavContainerHelper to create containers.

Ya gotta measure things

If the container setup process takes longer than normal, I'll want to know why.  Was it a performance issue downloading images or artifacts?  Or is there a performance issue with the VM?  Or did some error cause the script to fail prematurely?


Here's the PowerShell script I've setup to record the start time, end time, and elapsed time of the New-BcContainer process.  This is a sample that uses the values for building a BC container in my environment--you'll want to adjust the New-BcContainer parameter values to your preferred values.


 $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   
   }   


At the top of the script, I record the start time, then output that time in the log so that I can see when the script started.

I added a try/catch block so that even if the script fails, my script outputs the end time and elapsed time.

In the finally block, I record the time again, then calculate elapsed time.  The elapsed time is then output to the log.

Building a new named image vs. using an existing named image

In this example, I see that when the script had to build a new named image, it took 13 minutes to create the named image and then create the container.  But when it was able to use an existing named image, it only took 1 minute.

Good to know!

Now I can use this script to see how my dedicated physical server compares to my VMs.  I assume that the VMs will be slower, but I'm curious to see how much slower.


Steve Endow is a Microsoft MVP in Los Angeles.  He works with Dynamics 365 Business Central, Microsoft Power Automate, Power Apps, Azure, .NET, Dynamics GP, and SQL Server.

You can also find him on Twitter and YouTube

http://www.precipioservices.com



Automatically Create BC Docker Container - PowerShell Script version 3

 By Steve Endow I created this PowerShell script to automatically re-create my Business Central Docker Containers every morning. Version 3 o...