MZN.Office365.psm1
#### FUNCTIONS #### <# .Synopsis Starts an AD sync to Azure AD on the remote server .DESCRIPTION When a sync to Azure AD is required in a script, then this function can be used to remotely start the sync to Azure AD. Specify the policy type (delta or intial) and the module path (if the directory is not default) .EXAMPLE PS C:\Scripts> Start-ADSync -ComputerName Server01 PSComputerName RunspaceId Result -------------- ---------- ------ Server01 d5490783-7f1f-46bb-aa97-fa8d4cabdd32 Success Successfully started the AD Sync Cycle on target Server01 #> Function Start-ADSync{ [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium' )] Param ( #Specify the AAD Connect Server [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true )] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [Alias("ADConnectServer","DirSyncServer","ADSyncServer")] [string] $ComputerName, #Specifiy the AAD Connect Module Path on the AAD Connect Server [Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true )] [Alias("Module","Path")] [string] $modulePath = "C:\Program Files\Microsoft Azure AD Sync\Bin\ADSync\ADSync.psd1", #Specifiy the policy type that needs to sync [Parameter()] [Alias("Type")] [ValidateSet('Delta','Initial')] [string] $policyType = "Delta", #Switch to turn on Error logging [Switch]$ErrorLog, [String]$LogFile = '.\Force-ADSync.log' ) Process { #starts transcript to errorlog when error log is specified if($Errorlog){ Start-Transcript -Path $LogFile -Append } if ($pscmdlet.ShouldProcess($ComputerName, "Making a connection to the AD Connect Server")) { #trying to make a connection to the AD Connect Server Try{ $s = New-PSSession -ComputerName $ComputerName -EA Stop Write-Verbose "Successfully connected to the AD Connect server $Computername" } Catch{ Write-Warning "Unable to Connect to the AD Connect Server!" Write-Verbose $error[0] If ($ErrorLog){ Stop-Transcript } break } } if ($pscmdlet.ShouldProcess($ComputerName, "Importing the AD Connect Module")) { #Setting the script block in a variable $scriptBlock = { param( [String] $modulePath ) Import-Module $modulePath } #Importing the AD Connect Module Try{ Invoke-Command -Session $s -ScriptBlock $scriptBlock -ArgumentList $(,$modulePath) -ErrorAction inquire Write-Verbose "Successfully imported AD Connect Module from location $modulePath" } Catch{ Write-Warning "Unable to import AD Connect Module!" Write-Verbose $error[0] Remove-PSSession $s -ErrorAction SilentlyContinue If ($ErrorLog){ Stop-Transcript } break } } if ($pscmdlet.ShouldProcess($ComputerName, "Performing an AD Sync Cycle")) { #Setting the script block in a variable $scriptBlock = { param( [String] $policyType ) Start-ADSyncSyncCycle -PolicyType $policyType } #starting the AD Sync Cycle on the remote server try{ Invoke-Command -Session $s -ScriptBlock $scriptBlock -ArgumentList $(,$policyType) -ErrorAction Stop Write-Host "Successfully started the AD Sync Cycle on target $ComputerName" -ForegroundColor Green } catch{ Write-Warning "Unable to start the AD Sync Cylce!" Write-Verbose $error[0] } Finally{ #removing the session and stopping the transcript Remove-PSSession $s -ErrorAction SilentlyContinue If ($ErrorLog){ Stop-Transcript } } } } End { } } <# .Synopsis Connects to Office 365 .DESCRIPTION Connects to all instances of Office 365 for the tenant .EXAMPLE PS C:\Users> Connect-O365 .EXAMPLE PS C:\Users> Connect-O365 -Proxy:$true #> Function Connect-O365{ [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium' )] Param ( #Specifiy if a proxy is required. Default the IE Proxy settings are used [Parameter()] [switch] $Proxy = $false ) process { #Imports the installed Azure Active Directory module. Import-Module MSOnline #Capture administrative credential for future connections. $credential = get-credential #Set organization variable $org = $credential.UserName.Split("@")[1] $spoAdminURI = "https://" + $org.Split(".")[0] +"-admin.sharepoint.com" #Set proxy settings if($proxy -eq $true){ $proxySettings = New-PSSessionOption -ProxyAccessType IEConfig #Establishes Online Services connection to Office 365 Management Layer. Connect-MsolService -Credential $credential #login to Azure Login-AzureRmAccount -Credential $credential #Imports SharePoint Online session commands into your local Windows PowerShell session. Import-Module Microsoft.Online.Sharepoint.PowerShell Connect-SPOService -url $spoAdminURI -Credential $credential #Creates an Exchange Online session using defined credential. $ExchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential $credential -Authentication "Basic" -AllowRedirection -SessionOption $proxySettings Import-Module (Import-PSSession $ExchangeSession -AllowClobber) -Global #Connection to Skype Online Import-Module SkypeOnlineConnector $sfboSession = New-CsOnlineSession -Credential $credential -SessionOption $proxySettings Import-Module (Import-PSSession $sfboSession -AllowClobber) -Global #Connect to Azure AD Connect-AzureAD -Credential $credential } else{ #Establishes Online Services connection to Office 365 Management Layer. Connect-MsolService -Credential $credential #login to Azure Login-AzureRmAccount -Credential $credential #Imports SharePoint Online session commands into your local Windows PowerShell session. Import-Module Microsoft.Online.Sharepoint.PowerShell Connect-SPOService -url $spoAdminURI -Credential $credential #Creates an Exchange Online session using defined credential. $ExchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential $credential -Authentication "Basic" -AllowRedirection Import-Module (Import-PSSession $ExchangeSession -AllowClobber) -Global #Connection to Skype Online Import-Module SkypeOnlineConnector $sfboSession = New-CsOnlineSession -Credential $credential Import-Module (Import-PSSession $sfboSession -AllowClobber) -Global #Connect to Azure AD Connect-AzureAD -Credential $credential } } } <# .Synopsis Checks if the users location is configured and if not configures the location for NL and sets the required licences. .DESCRIPTION Checks if the users location is configured and if not configures the location for NL and sets the required licences. .EXAMPLE PS C:\WINDOWS\system32> Set-O365License -userPrincipalName test@contoso.com -licenseType EMS User test@contoso.com is licensed for Enterprise Mobility and Security! .EXAMPLE PS C:\WINDOWS\system32> $user = import-csv c:\temp\test.csv PS C:\WINDOWS\system32> $user | foreach{Set-O365License -userPrincipalName $_.userPrincipalName -location NL -licenseType EMS,O365E3} #> Function Set-O365License{ [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Low')] Param ( #Provide the UPN of the user [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [ValidateNotNull()] [ValidateNotNullOrEmpty()] [Alias("UPN","User","emailAddress")] $userPrincipalName, #Provide the required location [Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [ValidateSet('NL','DE')] $location = "NL", #Provide the required licenses [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [ValidateSet('O365E3','EMS')] [Alias("license")] [string[]] $licenseType, #Switch to turn on Error logging [Switch]$ErrorLog, [String]$LogFile = '.\Set-Office365License.log' ) Process { #start error logging if -errorlog parameter was set if($ErrorLog){ Start-Transcript -Path $LogFile -Append } if ($pscmdlet.ShouldProcess("Office365", "Checking if user $userPrincipalName is present in Office365")) { try { $User = Get-MsolUser -UserPrincipalName $userPrincipalName -ErrorAction stop $UsageLocation = $user.UsageLocation $License = $user.Licenses Write-Verbose "User found in Office 365." } catch { Write-Warning "Unable to find the user in Office 365!" Write-Verbose $error[0] If ($ErrorLog){ Stop-Transcript } break } } if ($pscmdlet.ShouldProcess("Office 365", "Checking if the location is set for user $userPrincipalName")) { if(!($UsageLocation)){ Write-Verbose "Usage location is not set for user $userPrincipalName. Setting location to $location." try { #set usage location to $location $user | Set-MsolUser -UsageLocation $location -ErrorAction stop write-verbose "Usage location set for $userPrincipalName to $location successfully." } catch { Write-Warning "Unable set the usage location for $userPrincipalName to $location!" Write-Verbose $error[0] } } elseif($location -ne $UsageLocation) { Write-Verbose "Current usage location for the user $userPrincipalName is $UsageLocation. Changing the usage location to $location." try { #set usage location to $location $user | Set-MsolUser -UsageLocation $location -ErrorAction stop write-verbose "Usage location set for $userPrincipalName to $location successfully." } catch { Write-Warning "Unable set the usage location for $userPrincipalName to $location!" Write-Verbose $error[0] } } else{ write-verbose "Current usage location for the user is $usageLocation. No action required." } } if ($pscmdlet.ShouldProcess("Office 365", "Checking if the required licenses are available for the user $userPrincipalName")) { $accountSKUs = Get-MsolAccountSku #checking for the licenses and setting these when not assigned switch($licenseType){ O365E3 { if($License.accountsku.skupartnumber -match "ENTERPRISEPACK"){ #User already has an Enterprise License write-host "$userPrincipalName already has an O365 E3 License" -ForegroundColor Green } else { #Enabling O365 E3 License write-verbose "Enabling O365 Enterprise license for User $userPrincipalName" try{ $user | Set-MsolUserLicense -AddLicenses ($accountSKUs|where{$_.AccountSkuId -match "ENTERPRISEPACK"}).accountSkuID -ea stop write-host "User $userPrincipalName is licensed for O365 Enterprise E3!" -ForegroundColor Green } catch{ Write-Warning "Unable to set the Office 365 E3 License for the user $userPrincipalName!" Write-Verbose $error[0] } } } EMS { #Checking and setting EMS License if($License.accountsku.skupartnumber -match "EMS"){ #User already has an Enterprise License write-host "$userPrincipalName already has an EMS License" -ForegroundColor Green } else { #Enabling O365 E3 License write-verbose "Enabling EMS license for user $userPrincipalName" try{ $user | Set-MsolUserLicense -AddLicenses ($accountSKUs|where{$_.AccountSkuId -match "EMS"}).accountSkuID -ea stop write-host "User $userPrincipalName is licensed for Enterprise Mobility and Security!" -ForegroundColor Green } catch{ Write-Warning "Unable to set the EMS License for the user $userPrincipalName!" Write-Verbose $error[0] } } } } } } End { if($ErrorLog){ Stop-Transcript } } } <# .Synopsis Starts mail migration to Office 365 .DESCRIPTION Starts mail migration to Office 365 #> Function Start-MailMigration{ [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Low')] Param ( #Provide the UPN of the user [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Alias("UPN","User","emailAddress")] $UserPrincipalName, #Provide the hostname of the onpremise exchange server [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [Alias('RemoteHost','LocalServer')] $RemoteHostName, #Provide the hostname of the onpremise exchange server [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] $DeliveryDomain, #Provide the on-premise credentials [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [System.Management.Automation.PSCredential] $OnPremCreds, #Switch to turn on Error logging [Switch]$ErrorLog, [String]$LogFile = '.\Migrate-Mail.log' ) Begin { } Process { #start error logging if -errorlog parameter was set if($ErrorLog){ Start-Transcript -Path $LogFile -Append } #execute migration to Office 365 if ($pscmdlet.ShouldProcess($UserPrincipalName, "Starting mailbox migration to Office 365.")) { try { #start move request to Office 365 for the completed mailbox New-MoveRequest -Identity $UserPrincipalName -Remote -RemoteHostName $RemoteHostName -BatchName "O365" -TargetDeliveryDomain $DeliveryDomain -RemoteCredential $OnPremCreds -BadItemLimit 1000 -ErrorAction stop -SuspendWhenReadyToComplete Write-Host "Started upload to Office 365 for user $UserPrincipalName" Write-Host "To check the progress use the following command while connect to Office 365: get-moverequest" Write-Host "To complete the move request user the following command while connect to Office 365: get-moverequest $UserPrincipalName | resume-moverequest" } catch { Write-Warning "Unable start the mail migration for user $UserPrincipalName!" Write-Verbose $error[0] } } } End { If ($ErrorLog){ Stop-Transcript } } } <# .Synopsis Set the rights on the agenda or calendar of the user Default to Reviewer and a secretary group to Editor .DESCRIPTION This CMDLET sets the mailbox permissions of the agenda (NL) or the calendar (NL) of the mailbox of the user to the default permissions. The user Default will be set to Reviewer The provided group will be set to Editor .EXAMPLE Set-MailboxDefaultPermission -UserName test@contoso.com -GroupName Secretariaat .EXAMPLE $users | %{Set-MailboxDefaultPermission -UserName $_.UserPrincipalName -GroupName $groupname} | out-file $report -Append .NOTES Author: Michael Zimmerman Date: 19/02/2018 #> Function Set-MailboxDefaultPermission{ [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium')] Param ( # Provide the name of the user which mailbox permissions will be altered [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [ValidateNotNullOrEmpty()] [Alias("user")] $UserName, # Provide the group name which will be set to editor [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=1)] [ValidateNotNullOrEmpty()] [Alias("group")] $GroupName ) Process { #get the mailbox try { Write-Verbose "Getting the mailbox of the user $username" $mailbox = get-mailbox $UserName -EA Stop } catch { Write-Error $Error[0] return } #check if the dutch or english calendar is used if($AgendaPermissions = get-MailboxFolderPermission ($mailbox.Alias + ":\Calendar") -ErrorAction silentlycontinue){ $AgendaFolder = ($mailbox.Alias + ":\Calendar") Write-Verbose "The user $username has an English calendar. Continuing..." } elseif($AgendaPermissions = Get-MailboxFolderPermission ($mailbox.Alias + ":\agenda") -ErrorAction silentlycontinue){ $AgendaFolder = ($mailbox.Alias + ":\agenda") Write-Verbose "The user $username has a Dutch calendar. Continuing..." } else{ Write-Warning "Could not get the calendar information of the user $UserName." return } #check if the correct permissions are already set for the default user and if not set the correct permissions if($AgendaPermissions | where{$_.user -match "Default" -and $_.AccessRights -match "Reviewer"}) { Write-verbose "The calendar permissions for mailbox $username to user Default are already set to reviewer." } else { if ($pscmdlet.ShouldProcess("mailbox $UserName", "Setting the mailbox permission of the user Default")) { try { set-MailboxFolderPermission $AgendaFolder -user Default -AccessRights Reviewer -EA stop | out-null Write-verbose "successfully added the reviewer access rights to the user Default on the mailbox $username." } catch { Write-error "Unable to add the reviewer access rights to the user Default on the mailbox $username." } } } #check if the correct permissions are already set for the default user and if not set the correct permissions if($AgendaPermissions | where{$_.user -Match $GroupName -and $_.AccessRights -match "Editor"}) { Write-verbose "The calendar permissions for mailbox $username to the group $groupname are already set to reviewer." } else { if ($pscmdlet.ShouldProcess("mailbox $UserName", "Setting the mailbox permission of the group $GroupName")) { try { add-MailboxFolderPermission $AgendaFolder -user $GroupName -AccessRights Editor | Out-Null Write-verbose "successfully added the Editor access rights to the group $GroupName on the mailboxcalendar of $username." } catch { Write-error "Unable to add the Editor access rights to the group $groupname on mailboxcalendar of $username." } } } $CurrentPermissionsDefault = Get-MailboxFolderPermission $AgendaFolder | where{$_.user -match "Default"} | select user,accessrights $CurrentPermissionsGroup = Get-MailboxFolderPermission $AgendaFolder | where{$_.user -match $GroupName} | select user,accessrights $hash = @{ UserName = $UserName "User Default Access Rights" = $CurrentPermissionsDefault.AccessRights "Group $GroupName Access Rights" = $CurrentPermissionsGroup.AccessRights } $Object = New-Object PSObject -Property $hash return $Object } } |