Home > Logging, PowerCLI, Virtual Machine, vSphere > Virtual Machine logging

Virtual Machine logging

February 27th, 2011 Leave a comment Go to comments

I recently received an interesting question in my mailbox. Someone wanted to know if it was possible to enable/disable the logging for a Virtual Machine through PowerCLI. These Virtual Machine logs can be a handy resource when analysing problems.
This logging option is available through the vSphere client when you select Edit Settings and then Options-Advanced-General. In that form there is a checkbox that allows you to enable/disable the virtual machine logging.

Afaik, this feature is not yet available through a PowerCLI cmdlet. But it is easily accessible through the VirtualMachine object.

Enable/disable logging

#requires -version 2
#requires -pssnapin VMware.VimAutomation.Core -version 4.1

function Set-VMLogging{
<#
.SYNOPSIS
	Activate or deactivate logging on a virtual machine
.DESCRIPTION
	The function activates or deactivates logging on a
	virtual machine. The function allows toggling of
	the current setting through the
.NOTES
	Author:  Luc Dekens
.PARAMETER VM
	The virtual machine
.PARAMETER Logging
	A switch that indicates if logging should be activated or
	deactivated
.PARAMETER Toggle
	A switch that indicates if the current logging setting should
	be toggled
.EXAMPLE
	PS> Set-VMLogging -VM $vm -Logging:$true
.EXAMPLE
	PS> Get-VM | Set-VMLogging -Logging:$false
.EXAMPLE
	PS> Set-VMLogging -VM $vm -Toggle:$true
#>

	[CmdletBinding(DefaultParametersetName="OnOff")]
	param(
	[parameter(Mandatory=$true,ValueFromPipeline=$true)]
	[PSObject[]]$VM,
	[Parameter(ParameterSetName="OnOff")]
	[switch]$Logging,
	[Parameter(ParameterSetName="Toggle")]
	[switch]$Toggle
	)

	begin{
		$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
		$spec.Flags = New-Object VMware.Vim.VirtualMachineFlagInfo
		if($psCmdlet.ParameterSetName -eq "OnOff"){
			$spec.Flags.enableLogging = $Logging
		}
	}

	process{
		foreach($obj in $VM){
			if($obj.GetType().Name -eq "string"){
				$obj = Get-VM -Name $obj
			}
			if($psCmdlet.ParameterSetName -eq "OnOff"){
				$obj | where {$_.Extensiondata.Config.Flags.enableLogging -eq (!$Logging)} | %{
					$_.Extensiondata.ReconfigVM($spec)
				}
			}
			else{
				$spec.Flags.enableLogging = !$VM.Extensiondata.Config.Flags.enableLogging
				$obj.Extensiondata.ReconfigVM($spec)
			}
		}
	}
}

Annotations

Line 34-37: To avoid that the Logging and Toggle switch be used together, I placed both of them in different parameter sets.

Line 41-45: The VirtualMachineConfigSpec object that we need to change the logging setting is constant for all calls. Except if the function is called with the Toggle parameter.

Line 33,49: The function defines the VM parameter as an array, that way the script can use a foreach loop. Even if the function is called with only 1 virtual machine, the $VM variable will still be an array, albeit with only 1 element.

Line 50-52: An simple emulation of the OBN (Object By Name) feature that the PowerCLI cmdlets offer. The virtual machines can be passed as string or as an object returned by the Get-VM cmdlet.

Line 53-61: The actual change of the logging flag is done with the ReconfigVM_Task. The function handles the Logging and the Toggle switch with the if-then-else construct.

While I was writing the above function I realised that it would also be handy to have a function to retreive these logs. With the help of the Copy-DatastoreItem it turns out that this is also a trivial task.

Retrieve the logs

#requires -version 2
#requires -pssnapin VMware.VimAutomation.Core -version 4.1

function Get-VMLog{
<#
.SYNOPSIS
	Retrieve the virtual machine logs
.DESCRIPTION
	The function retrieves the logs from one or more
	virtual machines and stores them in a local folder
.NOTES
	Author:  Luc Dekens
.PARAMETER VM
	The virtual machine(s) for which you want to retrieve
	the logs.
.PARAMETER Path
	The folderpath where the virtual machines logs will be
	stored. The function creates a folder with the name of the
	virtual machine in the specified path.
.EXAMPLE
	PS> Get-VMLog -VM $vm -Path "C:\VMLogs"
.EXAMPLE
	PS> Get-VM | Get-VMLog -Path "C:\VMLogs"
#>

	param(
	[parameter(Mandatory=$true,ValueFromPipeline=$true)]
	[PSObject[]]$VM,
	[parameter(Mandatory=$true)]
	[string]$Path
	)

	process{
		foreach($obj in $VM){
			if($obj.GetType().Name -eq "string"){
				$obj = Get-VM -Name $obj
			}
		}
		$logPath = $obj.Extensiondata.Config.Files.LogDirectory
		$dsName = $logPath.Split(']')[0].Trim('[')
		$vmPath = $logPath.Split(']')[1].Trim(' ')
		$ds = Get-Datastore -Name $dsName
		$drvName = "MyDS" + (Get-Random)
		New-PSDrive -Location $ds -Name $drvName -PSProvider VimDatastore -Root '\' | Out-Null
		Copy-DatastoreItem -Item ($drvName + ":" + $vmPath + "*.log") -Destination ($Path + "\" + $obj.Name + "\") -Force:$true
		Remove-PSDrive -Name $drvName -Confirm:$false
	}
}

Annotations

Line 35-37: An simple emulation of the OBN (Object By Name) feature that the PowerCLI cmdlets offer. The virtual machines can be passed as string or as an object returned by the Get-VM cmdlet.

Line 43: The function creates a PSDrive to map the datastore where the virtual machine logs are located. To avoid/minimise collisions with existing PSDrives, the script adds a random number to the name.

Line 45: The actual copy of the log files is done with the Copy-DatastoreItem cmdlet. Note that the function always uses the Force parameter, this means that any existing files will be overwritten.

Sample runs

To activate logging for a virtual machine, you can call the function like this

Set-VMLogging -VM MyVM -Logging:$true

To deactivate logging for a series of virtual machines, you can do something like this

$vm = Get-VM -Name MyVM
Set-VMLogging -VM $vm -Logging:$false

The function also provides a ‘toggle’ switch. This parameter will change the actual setting for logging.

Get-VM My* | Set-VMLogging -Toggle

To retrieve the logs for a virtual machine, you do

Get-VMLog -VM MyVM -Path "C:\VMLogs"


Note that the script assumes that the folder VMLogs already exists.

And you can do this for a number of virtual machines as well

Get-VM PC* | Get-VMLog -Path "C:\VMLogs"

You will find the virtual machine logs in the subfolders under C:\VMLogs

  1. David Mays
    December 5th, 2011 at 17:29 | #1

    I seem to not be able to get this script working with cli v5 and vsphere 4.1. Has something changed in 5? There is no error generated, just nothing happens.

    • December 5th, 2011 at 19:01 | #2

      @David, both scripts have a line at the top that says

      #requires -pssnapin VMware.VimAutomation.Core -version 4.1

      Try removing that line.
      The requirement will fail since you are using PowerCLI 5.

  1. March 11th, 2011 at 13:25 | #1
  2. March 18th, 2011 at 12:42 | #2