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!

#v2.0 - June 22, 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.securestring
$passwordFile = "D:\BCPowerShell\Gmail.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)"
}

$oldVersion = $currentVersion

#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
    $newVersion = (Get-InstalledModule $moduleName).Version.ToString()
    $message += "`nUpdate complete";
    $message += "`nCurrent version is now " + $newVersion;
        
    $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 + ": " + $newVersion;
    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

No comments:

Post a Comment

All comments must be reviewed and approved before being published. Your comment will not appear immediately.

How many digits can a Business Central Amount field actually support?

 by Steve Endow (If anyone has a technical explanation for the discrepancy between the Docs and the BC behavior, let me know!) On Sunday nig...