v10 NLog breaks previous versions in PowerShell

In previous versions we used NLog in PowerShell scripts, especially useful with custom PowerShell Sync Projects. It has been extremely useful for debugging connections and specific failures.

It was essentially loaded like this:

# Update to the correct path
$mypath = $MyInvocation.MyCommand.Path;
$parentPath = Split-Path $mypath -parent;
# Load NLog
$nlogPath = "$parentPath\Nlog.dll";
[System.Reflection.Assembly]::LoadFile($nlogPath);
function Import-Logger
{
	# Create a new Logger
	$Logger = [Nlog.LogManager]::GetLogger("MyLoggerName");
	return($Logger);
}
$global:Log = Import-Logger;
$Log.Debug("This is a logged message at Debug level.");

However, this now fails in v10. I see the NLog in v10 is of a v6.0.0 which has moved from LogManager to LogFactory (but switching to that fails with same error). I spent quite a bit of time looking at different ways of loading the DLL, all resulting in the same failure of "Unable to find type [NLog.LogFactory].".

So, I grabbed the nuGet 6.0.0 package, extracted it, and the above code was fine when loading those NLog.dll. So, there is definitely something about the NLog supplied in v10 that can't be loaded into PowerShell.

Any guidance on getting OneID NLog to work in PowerShell?

Parents
  • Right! Managed to crack this annoyance!

    Firstly, download the latest NuGet Package Latest NLog NuGet Package and change the extension from .nupkg to .zip. Extract the contents.

    Upload the \lib\netstandard2.1\NLog.dll to Software Loader in a sub-directory and tag to the Job Service and Administration Tools.

    Warning DO NOT REPLACE THE BASE NLOG.DLL - THIS WILL BREAK EVERYTHING!

    Next, the loading of the NLog in the PowerShell Script(s) has to be updated. Below is an example:

    #####################################################################################################################################################
    # Update to the correct path
    #####################################################################################################################################################
    $mypath = $MyInvocation.MyCommand.Path;
    $parentPath = Split-Path $mypath -parent;
    
    #####################################################################################################################################################
    # Load NLog - function needs to be early for loading sequence purposes
    #####################################################################################################################################################
    $nlogAssemblyPath  = "$parentPath\ps-nlog\NLog.dll";
    $nlogConfigPath = "$parentPath\nlog.config";
    $tempConfig = [System.IO.Path]::GetTempFileName()
    [System.Reflection.Assembly]::LoadFrom($nlogAssemblyPath);
    
    function Import-Logger
    {
    	<#
    		.SYNOPSIS
    			Initiates NLog logging.
    
    		.DESCRIPTION
    			Initiates NLog logging.
    
    		.EXAMPLE
    			 $global:Log = Import-Logger;
    
    		.NOTES
    			Author: Identity, Security, and Access Governance
    			Website: https://www.isag.melbourne/
    	#>
    	#####################################################################################################################################################
    	# Create a new Logger
    	#####################################################################################################################################################
    	$configXml = Get-Content -Path $nlogConfigPath;
    	$configXml = $configXml -replace '\$\{basedir\}', $parentPath;
    	# Load configuration in-memory using NLog
    	$configXml | Set-Content -Path $tempConfig
    	[NLog.LogManager]::Configuration = [NLog.Config.XmlLoggingConfiguration]::new($tempConfig)
    	$NLog = [NLog.LogManager]::GetLogger('Testing');
    	return($NLog);
    }
    
    #####################################################################################################################################################
    # Create global cache variables
    #####################################################################################################################################################
    New-Variable -Name 'NLog' -Value (Import-Logger) -Description 'NLogger' -Scope Global -Force;
    
    $NLog.Debug("This is a test.");

    Warning The appName is now dotnet so that will be the subdirectory for the log file.

    At the end of the synchronization process, the $tempConfig needs to be deleted:

    Remove-Item -Path $tempConfig -Force;
  • Apparently (according to colleague and I haven't confirmed), the base One ID NLog.dll will work as long as its loaded by pwsh.exe and not powershell.exe. However, it still does have the issue of ${basedir} being incorrect requiring the above -replace code.

Reply
  • Apparently (according to colleague and I haven't confirmed), the base One ID NLog.dll will work as long as its loaded by pwsh.exe and not powershell.exe. However, it still does have the issue of ${basedir} being incorrect requiring the above -replace code.

Children
No Data