-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create dynamic groups in AzureAD and the VB365 jobs accordingly #183
Open
d-works42
wants to merge
22
commits into
VeeamHub:master
Choose a base branch
from
d-works42:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 19 commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
97e166c
initial upload SharePoint job by Site ID
86de1bd
initial readme
d456aff
Update README.md
d-works42 b33f6fa
debug mode
6638498
cleaned org information
5ae314c
Update README.md
d-works42 7aa33c4
Merge branch 'VeeamHub:master' into master
d-works42 7ad8fe6
Merge branch 'VeeamHub:master' into master
d-works42 3c7710e
Merge branch 'VeeamHub:master' into master
d-works42 7095a42
Initial UserJobsDynamicGroups
1a9a067
Initial UserJobsDynamicGroups
782f45f
Merge branch 'master' of https://github.com/d-works42/powershell
44869db
small updates
d8b2051
formatting
33527b2
formatting
fea38c8
fixed a wring variable
79f2653
Merge branch 'VeeamHub:master' into master
d-works42 1554122
changed $org to $vbOrgObject
5afaa34
Merge branch 'master' of https://github.com/d-works42/powershell
df6cb6a
Merge branch 'VeeamHub:master' into master
d-works42 3b602b7
Update README.md
d-works42 46edaad
Add files via upload
d-works42 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
## VeeamHub | ||
Veeamhub projects are community driven projects, and are not created by Veeam R&D nor validated by Veeam Q&A. They are maintained by community members which might be or not be Veeam employees. | ||
|
||
## 🤝🏾 License | ||
Copyright (c) 2021 VeeamHub | ||
|
||
- [MIT License](LICENSE) | ||
|
||
## Project Notes | ||
**Author:** David Bewernick (@d-works42) | ||
|
||
**Version:** 1.1 | ||
|
||
**Function:** This script creates Azure AD dynamic groups to split up the users of a whole tenant based on the first two characters of their ObjectID. | ||
The number of groups beeing created is depending on the array of first and second character. | ||
Per default, this script will create 64 groups, since the first charakter will be from "0" to "f" and the second character will be grouped in 4 expression ranges. | ||
VB365 backup jobs will be created for every dynamic group and separatly for Exchange Online and OneDrive. | ||
|
||
**ATTENTION:** | ||
!!! You need to use the Microsoft AzureADPreview module since the parameter "MembershipRule" is only available in the beta of GraphAPI. | ||
-> Install-Module AzureADPreview -Scope CurrentUser -AllowClobber !!! | ||
|
||
**Requires:** AzureADPreview Module and a Microsoft subscription which includes at least Azure AD Premium P1 features. | ||
|
226 changes: 226 additions & 0 deletions
226
VB365-UserJobsDynamicGroups/VB365-UserJobsDynamicGroups.ps1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,226 @@ | ||
<# | ||
.SYNOPSIb | ||
Creating Azure AD dynamic groups with user membership based on regex and creating VB365 backup jobs for every group. | ||
|
||
.DESCRIPTION | ||
!!! You need to use the Microsoft AzureADPreview module since the parameter "MembershipRule" is only available in the beta of GraphAPI. | ||
-> Install-Module AzureADPreview -Scope CurrentUser -AllowClobber !!! | ||
|
||
Requires: Microsoft subscription which includes at least Azure AD Premium P1 features. | ||
|
||
This script creates Azure AD dynamic groups to split up the users of a whole tenant based on the first two characters of their ObjectID. | ||
The number of groups beeing created is depending on the array of first and second character. | ||
Per default, this script will create 64 groups, since the first charakter will be from "0" to "f" and the second character will be grouped in 4 expression ranges. | ||
VB365 backup jobs will be created for every dynamic group and separatly for Exchange Online and OneDrive. | ||
|
||
.NOTES | ||
Version: 1.1 | ||
Author: David Bewernick (david.bewernick@veeam.com) | ||
Creation Date: 03.04.2023 | ||
|
||
.CHANGELOG | ||
1.0 31.03.2023 Script created | ||
1.1 03.04.2023 Description and dynamic membership rules extention | ||
|
||
#> | ||
|
||
# Enable (1) or disable (0) debug messages | ||
$debug = 0 | ||
|
||
# Install-Module AzureADPreview -Scope CurrentUser -AllowClobber #uncomment this to install the AureADPreview module | ||
|
||
$timestampFileName = get-date -Format "yyyy-mm-dd_HH-mm-ss" | ||
[string[]]$script:arrFirstChar = @("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f") #array of characters for the regex | ||
[string[]]$Script:arrScndChar = @('0-3','4-7','8-9a-b','c-f') | ||
|
||
# Variables to fit your needs | ||
$OrgName = "XYZ.onmicrosoft.com" # The name of your M365 organization | ||
$RepoName = "XYZ-Repo" # Define the target repository | ||
$LogFile = "VBO-CreateDynamicGroups.log" #logfile name | ||
$GroupNameFile = "DynamicGroupsList_$timestampFileName.log" #file to export group names | ||
$strGroupNameStart = "VB365-UserBackup_" #start of the Azure AD dynamic group names | ||
$strJobNameStartExch = "Exch_" #start of the Exchange Online job names | ||
$strJobNameStartOD = "OD_" #start of the OneDrive job names | ||
|
||
# Get the organizsation in an object | ||
$vbOrgObject = Get-VBOOrganization -Name $OrgName | ||
# Get the VB365 target repository object | ||
$vbRepoObject = Get-VBORepository -Name $RepoName | ||
|
||
# Define the backup schedule for new jobs (Options Info: https://helpcenter.veeam.com/archive/vbo365/40/powershell/new-vbojobschedulepolicy.html) | ||
$vbSchedType = "daily" | ||
$vbSchedDailyType = "Everyday" | ||
$vbSchedStartHr = "22" | ||
$vbSchedStartMin = "00" | ||
|
||
# Time to delay in minutes for the next created job | ||
$global:vbSchedDelayMin = "2" | ||
|
||
# Create the initial start time value | ||
$global:vbDailyTime = "$vbSchedStartHr" + ":" + "$vbSchedStartMin" + ":00" | ||
|
||
#Function for logging and console output | ||
function Write-Log($Info, $Status){ | ||
$timestamp = get-date -Format "yyyy-mm-dd HH:mm:ss" | ||
switch($Status){ | ||
Info {Write-Host "$timestamp $Info" -ForegroundColor Green ; "$timestamp $Info" | Out-File -FilePath $LogFile -Append} | ||
Status {Write-Host "$timestamp $Info" -ForegroundColor Yellow ; "$timestamp $Info" | Out-File -FilePath $LogFile -Append} | ||
Warning {Write-Host "$timestamp $Info" -ForegroundColor Yellow ; "$timestamp $Info" | Out-File -FilePath $LogFile -Append} | ||
Error {Write-Host "$timestamp $Info" -ForegroundColor Red -BackgroundColor White; "$timestamp $Info" | Out-File -FilePath $LogFile -Append} | ||
default {Write-Host "$timestamp $Info" -ForegroundColor white "$timestamp $Info" | Out-File -FilePath $LogFile -Append} | ||
} | ||
} | ||
|
||
# Create a time object for later modification | ||
$global:vbSchedTimeObj = New-Object DateTime 2022, 1, 1, $vbSchedStartHr, $vbSchedStartMin, 0, ([DateTimeKind]::Utc) | ||
if($debug="1"){Write-Host "Initial vbSchedTimeObj: $vbSchedTimeObj"} | ||
|
||
# Build the initial backup job schedule | ||
$global:vbSchedule = New-VBOJobSchedulePolicy -Type $vbSchedType -DailyType $vbSchedDailyType -DailyTime $vbDailyTime | ||
Write-Log -Info "New jobs will be created with this initual schedule:`n`t`t`t`t Type: $($vbSchedule.Type) `n`t`t`t`t DailyType: $($vbSchedule.DailyType) `n`t`t`t`t DailyTime: $($vbSchedule.DailyTime) `n`t`t`t`t Delay for the next job: $vbSchedDelayMin" -Status Info | ||
|
||
function AddTimeDelay(){ | ||
|
||
if($debug="1"){Write-Host "vbSchedTimeObj before delay: $vbSchedTimeObj"} | ||
|
||
# Add the delay minutes | ||
$global:vbSchedTimeObj = $vbSchedTimeObj.AddMinutes($vbSchedDelayMin) | ||
if($debug="1"){Write-Host "vbSchedTimeObj after delay: $vbSchedTimeObj"} | ||
|
||
# Recreate the DailyTime value | ||
$global:vbDailyTime = $vbSchedTimeObj.ToString("HH:mm:ss") | ||
if($debug="1"){Write-Host "vbDailyTime: $vbDailyTime"} | ||
|
||
# Recreate the schedule object with the new start time | ||
$global:vbSchedule = New-VBOJobSchedulePolicy -Type $vbSchedType -DailyType $vbSchedDailyType -DailyTime $vbDailyTime | ||
if($debug="1"){Write-Host "vbSchedule: $vbSchedule"} | ||
} | ||
|
||
#Function to create the Azure AD dynamic groups and backup jobs in VB365 | ||
function create-groups(){ | ||
$i=0 | ||
while($i -lt $arrFirstChar.length){ #go through the array for the first character | ||
$j=0 | ||
while($j -lt $arrScndChar.length){ #go through the array for the second character | ||
$strRegex = '^' + $arrFirstChar[$i] + '[' + $arrScndChar[$j] + ']' #building the regex based on the array strings | ||
$strGroupName = $strGroupNameStart + $arrFirstChar[$i] + $arrScndChar[$j] #create the group name | ||
$strMembershipRule = '(user.objectID -match "' + $strRegex + '") and (user.mail -ne "$null") and (user.accountEnabled -eq true) and (user.assignedPlans -ne $null) and (user.assignedPlans -any (assignedPlan.capabilityStatus -eq "Enabled"))' #define the Membership rule based on the regex and additional properties" | ||
#Write-Output $strGroupName | ||
#Write-Output $strRegex | ||
#Write-Output $strMembershipRule | ||
|
||
if((Get-AzureADMSGroup | where{$_.DisplayName -eq $strGroupName}) -eq $null) { | ||
try { | ||
New-AzureADMSGroup -DisplayName "$strGroupName" -MailNickname "$strGroupName" -Description "Group for VBO backup with rule $strRegex" -MailEnabled $false -GroupTypes {DynamicMembership} -SecurityEnabled $true -MembershipRule "$strMembershipRule" -MembershipRuleProcessingState 'on' #this is finally creating the dynamic group in AzureAD | ||
Write-Log -Info "Group $strGroupName created with MembershipRule $strMembershipRule" -Status Info | ||
$strGroupName | Out-File -FilePath $GroupNameFile -Append # write groupname to CSV file | ||
} | ||
catch{ | ||
Write-Log -Info "$_" -Status Error | ||
Write-Log -Info "Group $strGroupName could not be created" -Status Error | ||
exit 99 | ||
} | ||
} | ||
else { | ||
Write-Log -Info "Group $strGroupName is already existing" -Status Status | ||
$strGroupName | Out-File -FilePath $GroupNameFile -Append # write groupname to CSV file | ||
} | ||
|
||
# Call the function to create or modify the backup job | ||
create-jobs($strGroupName) | ||
|
||
$j++ | ||
} | ||
$i++ | ||
} | ||
|
||
} | ||
|
||
|
||
|
||
# Function to create the backup jobs based on the group name | ||
function create-jobs ($strGroupName){ | ||
|
||
# get the organization group in an object | ||
$orggroup = Get-VBOOrganizationGroup -Organization $vbOrgObject -DisplayName $strGroupName | ||
# create backup job item objects for Exchange and OneDrive | ||
$ExchJobItem = New-VBOBackupItem -Group $orggroup -Mailbox -ArchiveMailbox | ||
$ODJobItem = New-VBOBackupItem -Group $orggroup -OneDrive | ||
|
||
$ExchJobName = $strJobNameStartExch + $strGroupName | ||
$ODJobName = $strJobNameStartOD + $strGroupName | ||
|
||
### Modify or create Exchange backup job ### | ||
|
||
# Check if job exist and add group | ||
|
||
if ($VbJob=Get-VBOJob | ? {$_.Name -like $ExchJobName}){ | ||
Write-Log -Info "$ExchJobName exists, adding $strGroupName" -Status Info | ||
Add-VBOBackupItem -Job $VbJob -BackupItem $ExchJobItem | ||
|
||
} | ||
|
||
# If job does not exist create it including the site | ||
else { | ||
Write-Log -Info "Creating $ExchJobName and adding $strGroupName" -Status Info | ||
Add-VBOJob -Organization $vbOrgObject -Name "$ExchJobName" -Repository $vbRepoObject -SchedulePolicy $vbSchedule -SelectedItems $ExchJobItem | ||
|
||
# Increase the time for the next schedule | ||
if($debug="1"){Write-Host "Schedule before delay: $($vbSchedule.DailyTime)"} | ||
AddTimeDelay | ||
if($debug="1"){Write-Host "Schedule after delay: $($vbSchedule.DailyTime)"} | ||
} | ||
|
||
### Modify or create OneDrive backup job ### | ||
|
||
# Check if job exist and add group | ||
|
||
if ($VbJob=Get-VBOJob | ? {$_.Name -like $ODJobName}){ | ||
Write-Log -Info "$ODJobName exists, adding $strGroupName" -Status Info | ||
Add-VBOBackupItem -Job $VbJob -BackupItem $ODJobItem | ||
|
||
} | ||
|
||
# If job does not exist create it including the site | ||
else { | ||
Write-Log -Info "Creating $ODJobName and adding $strGroupName" -Status Info | ||
Add-VBOJob -Organization $vbOrgObject -Name "$ODJobName" -Repository $vbRepoObject -SchedulePolicy $vbSchedule -SelectedItems $ODJobItem | ||
|
||
# Increase the time for the next schedule | ||
if($debug="1"){Write-Host "Schedule before delay: $($vbSchedule.DailyTime)"} | ||
AddTimeDelay | ||
if($debug="1"){Write-Host "Schedule after delay: $($vbSchedule.DailyTime)"} | ||
} | ||
} | ||
|
||
### MAIN ### | ||
|
||
# Connecting to AzureAD | ||
Write-Log -Info "Trying to connect to AzureAD..." -Status Info | ||
try { | ||
Connect-AzureAD | ||
$ConnectionAccountName = Get-AzureADCurrentSessionInfo | select Account | ||
Write-Log -Info "Connection successful with $ConnectionAccountName" -Status Info | ||
} | ||
catch { | ||
Write-Log -Info "$_" -Status Error | ||
Write-Log -Info "Could not connect with $ConnectionAccountName" -Status Error | ||
exit 99 | ||
} | ||
|
||
|
||
Write-Log -Info "Creating the groups and jobs..." -Status Info | ||
|
||
create-groups | ||
|
||
#Disconnecting from AzureAD | ||
Write-Log -Info "Trying to disconnect from AzureAD..." -Status Info | ||
try { | ||
Disconnect-AzureAD | ||
Write-Log -Info "Successfully disconnected" -Status Info | ||
} | ||
catch { | ||
Write-Log -Info "$_" -Status Error | ||
Write-Log -Info "Could not disconnect from AzureAD" -Status Error | ||
exit 99 | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update the README file letting others know which Veeam Backup for Microsoft 365 versions the script was tested against and/or supports.
Here's a sample README you can use as a reference:
https://github.com/VeeamHub/powershell/blob/master/VB365-ExportMailboxToPST/README.md
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I somehow came over this comment, edited now.