Write-Log not working in custom function

Hello, I’m new to the deploy toolkit project and looking for a little help. I have a custom function in AppDeployToolkitExtensions.ps1 that uninstalls Appx packages. I’m leveraging the Remove-AppxProvisionedPackage cmdlet but I want logging so that’s why the custom function:

Function Uninstall-AppxPackage
{
	<#
	.DESCRIPTION
		Uninstall-AppxPackage removes all AppX package and provisionings matching the specified package name.
	.PARAMETER PackageName
		The name of the package to uninstall. Performs a contains match on the application display name by default.
	.PARAMETER Exact
		Specifies that the named application must be matched using the exact name.
	.PARAMETER LogName
		Overrides the default log file name.
	.EXAMPLE
		Uninstall-AppxPackage -PackageName 'Microsoft.Office.Excel_16001'
	#>
	[CmdletBinding()]
	Param (
		[Parameter(Mandatory = $true)][string]$PackageName,
		[Parameter(Mandatory = $false)][string]$LogName = "",
		[Parameter(Mandatory = $false)][switch]$Exact = $false
	)
	
	$Source = $MyInvocation.MyCommand
		
	If ($Exact) { $Name = $PackageName }
	Else { $Name = "*$PackageName*" }
		
	$appxProvisionedPackages = Get-AppxProvisionedPackage -Online | Where-Object { $_.PackageName -like $Name }
	Write-Log -Message "Found [$($appxProvisionedPackages.Count)] application(s) that matched the specified criteria [$Name]." -Source $Source
	
	If ($appxProvisionedPackages.Count -gt 0)
	{
		ForEach ($appxProvisionedPackage In $appxProvisionedPackages)
		{
			$OEMLogFile = $configMSILogDir + '\' + $appxProvisionedPackage.DisplayName + ' ' + $appxProvisionedPackage.Version + ' Uninstall.log'
			If ($LogName -ne "") { $OEMLogFile = $configMSILogDir + '\' + $LogName }
			
			$DismLogContent = ""; If (Test-Path ($env:windir + '\logs\DISM\dism.log')) { $DismLogContent = Get-Content -Path ($env:windir + '\logs\DISM\dism.log') -Raw }
			
			Write-Log -Message "Remove provisioning for $($appxProvisionedPackage.PackageName)" -Source $Source
			$appxProvisionedPackage | Remove-AppxProvisionedPackage -Online
			
			Write-Log -Message "Remove application $($appxProvisionedPackage.PackageName)" -Source $Source
			Get-AppxPackage -AllUsers | Where-Object { $_.PackageFullName -like ($appxProvisionedPackage.DisplayName + "_" + $appxProvisionedPackage.Version + "*") } | Remove-AppxPackage
			
			Try
			{
				If ($DismLogContent.Length -gt 0) { Set-Content -Path $OEMLogFile -Value ((Get-Content -Path ($env:windir + '\logs\DISM\dism.log') -Raw).Replace($DismLogContent, '')) }
				Else { Set-Content -Path $OEMLogFile -Value (Get-Content -Path ($env:windir + '\logs\DISM\dism.log') -Raw) }
				Write-Log -Message "OEM log file $OEMLogFile generated." -Source $Source
			}
			Catch
			{
				Write-Log -Message "Failed to create OEM log file $OEMLogFile." -Source $Source -Severity 3
				If (-not $ContinueOnError) { Throw "Failed to create OEM log file $OEMLogFile." }
				Return
			}
		}
	}
	Else
	{
		Write-Log -Message "No applications that matched the specified criteria [$Name] were found for removal. Continue..." -Source $Source
	}
}

The problem I’m having is that Write-Log isn’t actually writing anything to the log file. Other functions in AppDeployToolkitExtensions.ps1 that leverage Write-Log work as expected. And if I run the code in Sapien I can see the output that I’d expect to be written to the log.

The function is called in Deploy-Application.ps1 like this:

$AppxPackageNames = @('Microsoft.Office.Excel_16001', 'Microsoft.Office.PowerPoint_16001', 'Microsoft.Office.Word_16001')
ForEach ($package In $AppxPackageNames)	{ Uninstall-AppxPackage -PackageName $package }
#$AppxPackageNames | ForEach-Object { Uninstall-AppxPackage -PackageName $_ }

I actually use the Remove-MSIApplications right before this and it logs fine too. I’m kinda out of ideas on what the problem could be. Any help would be greatly appreciated.

Edit: Everything else in the function works as expected.

Can you try placing the function in AppDeployToolkitExtensions.ps1 under the custom function section?

You mentioned you have other functions there – is there a particular reason this one is not?

I mentioned that the function is in AppDeployToolkitExtensions.ps1 just above the code block.

Thanks!

Sorry, I misread that!

What context is the function running in vs the rest of the script? It is possible that this function/commands are running as the normal user but the log is not writable to the user. Try temporarily change the log location to someone globally writable and see if that helps.

If this is the case, it is an issue on our radar and we are trying to figure out the best way to handle it.

The context of the script doesn’t change thru its execution (at least not by me). And here’s another odd bit, if I run the Deploy-Application.ps1 thru the Sapien PS editor the lines I’d expect to be written to the log file show up in the output stream. I’ve also got an Install-AppxPackage function in AppDeployToolkitExtensions.ps1 and it exhibits the same behavior.

I use Write-Log in my Extensions just fine. In fact I have about 10 functions there and all of them write to the log without issues. I dont use Sapien though. Not sure how it works. Try creating a simple function that just logs something and run the actual toolkit to test it.

luki1412,

I have several other functions that use Write-Log both before and after these two particular functions run and they work as expected. It’s just when used within two specific functions that it does not work. That’s why I started this post. :grin:

I tested your function and it writes to the console but not to the log.
That is strange.

So then either I’m not crazy or we both are :laughing:

The log path that Write-Log constructs is incorrect and so the call fails.

Cool, thanks for tracking that down. Where do I go from here? Can I modify the Write-Log call in my function or is this a bug that would need to be corrected in the AppDeployToolkitMain.ps1 code?

I figured it out. The path does not get constructed correctly and it only happens in this function because in this function you use a parameter with the name $logName which is used inside our script for filename that is gonna be used for logging. You use it in parameters and set it to empty string by default. That replaces the filename in the “soon to be path” which results in an invalid file path: <path>\$logName since <path>\ is an invalid path for a filename. So for now, just change the parameter name.

That did it, thanks so much! I changed $LogName to $OEMLogName in both functions and everything’s happy again.

1 Like