Use PowerShell to add Holidays to Outlook Calendar

Geeking around with PowerShell today trying to add all company holidays to my Outlook calendar. In the script, I’m creating all day appointments and setting the Show As to out of office. Simple enough!

CLOSE Outlook before running the script.

function get-mailfolders {
	$outlookfolders = @()
	$outlook = New-Object -ComObject Outlook.Application
	foreach ($folder in $outlook.Session.Folders){ 

		foreach($mailfolder in $folder.Folders ) {
			$olkf = New-Object PSObject -Property @{
				Path = $($mailfolder.FullFolderPath)
				EntryID = $($mailfolder.EntryID)
				StoreID = $($mailfolder.StoreID)
			} 

			$outlookfolders += $olkf
		}
	}
	$outlookfolders
}

$outlook = new-object -com Outlook.Application
$folder = get-mailfolders | where {$_.Path -like "*calendar*" -and $_.Path -and $_.Path -like "*$mailbox*"}
$calendar = $outlook.Session.GetFolderFromID($folder.EntryID, $folder.StoreID) 

$holidays = @{"01/01/2017"="New Year’s Day"; "01/16/2017"="Martin Luther King Day"; "02/02/2017"="Presidents Day"; "05/29/2017"="Memorial Day"; `
	"07/04/2017"="Independence Day"; "11/4/2017"="Labor Day"; "11/23/2017"="Thanksgiving Break"; "11/24/2017"="Thanksgiving Break"; "12/25/2017"="Christmas Day"}

foreach($holiday in $holidays.GetEnumerator() | Sort Key)
{
	[string]$hName = $holiday.Value
	$hDate = Get-Date $holiday.Key

	$appt = $calendar.Items.Add(1)
	$appt.Start = $holiday.key.ToString()
	$appt.AllDayEvent = $true
	$appt.Subject = $hName
	$appt.Body = $hName

	<#
	Show As / Status
	0 = Free
	1 = Tentative
	2 = Busy
	3 = Out of Office
	#>
	$appt.BusyStatus = 3

	$appt.Save()
}

You might see this error if you haven’t CLOSED Outlook:

new-object : Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to
the following error: 80080005 Server execution failed (Exception from HRESULT: 0x80080005 (CO_E_SERVER_EXEC_FAILURE)).
At C:\Code\PS\SPO_BHP\Set_Holidays.ps1:19 char:12
+ $outlook = new-object -com Outlook.Application
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (:) [New-Object], COMException
+ FullyQualifiedErrorId : NoCOMClassIdentified,Microsoft.PowerShell.Commands.NewObjectCommand

This post helped guide me in the right direction:
Create a calendar item

Get all Groups and Users in a Site Collection or Web

Recently a user contacted me asking how to get all the groups and users in a site and subsites.

Both example will output to the C:\ drive of the server.

This script will output all the groups and user from the root of a site collection and all the subsites.

$site = Get-SPSite "http://sharepointed.com"

$userOutput = @()

foreach($subWebs in $site.AllWebs)
{
Write-Host $subWebs.Title

$groups = $subWebs.sitegroups

foreach($group in $groups)
{
$object = New-Object PSobject
$object | Add-Member -Name ‘Web URL’ -MemberType Noteproperty -Value $web.URL
$object | Add-Member -Name ‘Web Title’ -MemberType Noteproperty -Value $web.Title
$object | Add-Member -Name ‘Group’ -MemberType Noteproperty -Value $group.Name
$userOutput += $object

foreach($userG in $group.users)
{
$object = New-Object PSobject
$object | Add-Member -Name ‘Web URL’ -MemberType Noteproperty -Value $web.URL
$object | Add-Member -Name ‘Web Title’ -MemberType Noteproperty -Value $web.Title
$object | Add-Member -Name ‘Group’ -MemberType Noteproperty -Value $group.Name
$object | Add-Member -Name ‘Account’ -MemberType Noteproperty -Value $userG.Name

$userOutput += $object
}
}
}

$userOutput | export-csv c:\site_collection_$(get-date -f yyyy-MM-dd-hhmmss).csv -notypeinformation

 

This script will output all the groups and users from a single web.

$web = Get-SPWeb "http://sharepointed.com/sites/taco/SubSite"

$userOutput = @()

$groups = $web.Groups
$users = $web.Users

#get groups and users in the groups
foreach($group in $groups)
{
$object = New-Object PSobject
$object | Add-Member -Name 'Web URL' -MemberType Noteproperty -Value $web.URL
$object | Add-Member -Name 'Web Title' -MemberType Noteproperty -Value $web.Title
$object | Add-Member -Name 'Group' -MemberType Noteproperty -Value $group.Name
$userOutput += $object

foreach($userG in $group.users)
{
$object = New-Object PSobject
$object | Add-Member -Name 'Web URL' -MemberType Noteproperty -Value $web.URL
$object | Add-Member -Name 'Web Title' -MemberType Noteproperty -Value $web.Title
$object | Add-Member -Name 'Group' -MemberType Noteproperty -Value $group.Name
$object | Add-Member -Name 'Account' -MemberType Noteproperty -Value $userG.Name

$userOutput += $object
}
}
#get users not in groups
foreach($user in $users)
{
$object = New-Object PSobject
$object | Add-Member -Name 'Web URL' -MemberType Noteproperty -Value $web.URL
$object | Add-Member -Name 'Web Title' -MemberType Noteproperty -Value $web.Title
$object | Add-Member -Name 'Group' -MemberType Noteproperty -Value ""
$object | Add-Member -Name 'Account' -MemberType Noteproperty -Value $user.Name

$userOutput += $object
}

$userOutput | export-csv c:\web_$(get-date -f yyyy-MM-dd-hhmmss).csv -notypeinformation