I was at my cousin’s graduation ball last weekend. As took my digital camera with me I have a lot of pictures now. The easiest way to deliver it to my cousin is to burn them all to CD (OK – maybe you know better methods :) When I was burning these pictures to a CD I had an idea to try to burn them directly from the console. To use something like:

PS C:\> cd c:\Pictures\2012-12-15-GraduationBall
PS C:\Pictures\2012-12-15-GraduationBall> Out-CD

After few seconds I found great article about burning directly from Windows and decided to convert it to PowerShell.

function Out-CD
{
	[CmdletBinding()]

	param (
		$Path = $PWD
	)

	BEGIN
	{
		try
		{
			Write-Verbose 'Creating COM Objects.'

			$DiskMaster      = New-Object -com IMAPI2.MsftDiscMaster2
			$DiscRecorder    = New-Object -com IMAPI2.MsftDiscRecorder2
			$FileSystemImage = New-Object -com IMAPI2FS.MsftFileSystemImage
			$DiscFormatData  = New-Object -com IMAPI2.MsftDiscFormat2Data
		}
		catch
		{
			$err = $Error[0]
			Write-Error $err
			return
		}
	}

	PROCESS
	{
		Write-Verbose 'Initializing Disc Recorder.'
		$id = $DiskMaster.Item(0)
		$DiscRecorder.InitializeDiscRecorder($id)

		Write-Verbose 'Assigning recorder.'
		$dir = $FileSystemImage.Root
		$DiscFormatData.Recorder = $DiscRecorder
		$DiscFormatData.ClientName = 'PowerShell Burner'

		Write-Verbose 'Multisession?'
		if (-not $DiscFormatData.MediaHeuristicallyBlank)
		{
			try
			{
				$FileSystemImage.MultisessionInterfaces = $DiscFormatData.MultisessionInterfaces
				Write-Verbose 'Importing existing session.'

				$FileSystemImage.ImportFileSystem() | Out-Null
			}
			catch
			{
				$err = $Error[0]
				Write-Error $err
				return
			}
		}
		else
		{
			Write-Verbose 'Empty medium.'
			$FileSystemImage.ChooseImageDefaults($DiscRecorder)
		}

		Write-Verbose "Adding directory tree ($Path)."
		$dir.AddTree($Path, $true)

		Write-Verbose 'Creating image.'
		$result = $FileSystemImage.CreateResultImage()
		$stream = $result.ImageStream

		Write-Verbose 'Burning.'
		$DiscFormatData.Write($stream)

		Write-Verbose 'Done.'
	}

	END { }
}

If you want to see detailed description, please check mentioned article. Briefly – as a default it will burn your actual folder (including it’s root name). If you want to burn just content, change $true to $false at line 63. It also supports multisessions disks (import of old session is at line 47).

Please note that there is no deep error checking and it will use first available CD drive for burning (line 31). At the beginning I had also check for other drives (and I compared it with results of Win32_CDROMDrive WMI class), but then I decided to remove it from this version.

If I want to burn more folders, I can just use this:

PS C:\test> Out-CD -Verbose
VERBOSE: Creating COM Objects.
VERBOSE: Initializing Disc Recorder.
VERBOSE: Assigning recorder.
VERBOSE: Multisession?
VERBOSE: Empty medium.
VERBOSE: Adding directory tree (C:\test).
VERBOSE: Creating image.
VERBOSE: Burning.
VERBOSE: Done
PS C:\test> cd C:\temp
PS C:\temp> Out-CD -Verbose
VERBOSE: Creating COM Objects.
VERBOSE: Initializing Disc Recorder.
VERBOSE: Assigning recorder.
VERBOSE: Multisession?
VERBOSE: Importing existing session.
VERBOSE: Adding directory tree (C:\temp).
VERBOSE: Creating image.
VERBOSE: Burning.
VERBOSE: Done
PS C:\temp> ls d:
 
Directory: D:\
 
Mode LastWriteTime Length Name
 
d-r– 17-Dec-12 8:18 PM temp
d-r– 11-Dec-12 2:16 PM test