From 8fe24d44bbe65f10fa6ef63af62e5c4518fb2fae Mon Sep 17 00:00:00 2001 From: Gal Szkolnik Date: Fri, 21 Jul 2023 00:01:04 +0000 Subject: [PATCH] Fix: Initial connection check when failed would not exit --- ASSIGNMENT-01.ps1 | 562 +++++++++++++++++++++++----------------------- 1 file changed, 281 insertions(+), 281 deletions(-) diff --git a/ASSIGNMENT-01.ps1 b/ASSIGNMENT-01.ps1 index ff69205..75247c4 100644 --- a/ASSIGNMENT-01.ps1 +++ b/ASSIGNMENT-01.ps1 @@ -1,282 +1,282 @@ -# establish Logging mechanism - -class LogEntry { - [bool]$Active=$true - [DateTime]$Timestamp - [string]$Operation - [string]$Description - [TimeSpan]$Duration - [String]$Status - - LogEntry( - [String]$Operation, - [String]$Description, - [switch]$Closed=$false - ){ - if( $Closed ) { $this.Active=$false } - $this.Timestamp=[DateTime]::Now - $this.Operation=$Operation - $this.Description=$Description - $this.Duration=[TimeSpan]::Zero - $this.Status="Open" - } - - [LogEntry]UpdateLogEntry( - [Switch]$Close, - [String]$Status, - [switch]$Quiet - ){ - if( $Close ) { - $this.Active = $false - } - $this.Duration = [DateTime]::Now - $this.Timestamp - if($Status) { $this.Status = $Status } - - if( -not $Quiet ) { - Write-Host -ForegroundColor Gray "Update " -NoNewline - Write-Host "$($this.Operation)/$($this.Description), $($this.Status)" - } - - return $this; - } -} - -class LogTrail { - [System.Collections.Generic.List[LogEntry]]$logs - - LogTrail(){ - $this.logs = [System.Collections.Generic.List[LogEntry]]::new() - } - - [LogEntry]NewLogEntry( - [LogEntry]$LogEntry, - [switch]$Quiet=$false - ){ - if( -not $Quiet ) { - Write-Host -ForegroundColor Cyan "Starting " -NoNewline - Write-Host "$($LogEntry.Operation) / $($LogEntry.Description)..." - } - $this.logs.Add($LogEntry) - return $LogEntry - } - - [LogEntry]NewLogEntry( - [String]$Operation, - [String]$Description, - [bool]$Quiet=$false - ){ - return $this.NewLogEntry( - [LogEntry]::new( - $Operation,$Description,$false - ) - ,$Quiet - ) - } - [LogEntry]NewLogEntry( - [String]$Operation, - [String]$Description - ){ - return $this.NewLogEntry( - $Operation, - $Description, - $false - ) - } - - [LogEntry]NewClosedLogEntry( - [String]$Operation, - [String]$Description, - [switch]$Quiet=$false - ){ - return $this.NewLogEntry( - [LogEntry]::new( - $Operation,$Description,$false - ) - ,$Quiet - ) - } -} -$script:LogTrail = [LogTrail]::new() - -function Invoke-LoggedAction{ -[CmdletBinding()]param( - [Parameter(Mandatory,Position=0)] - [scriptblock]$Action, - [Parameter(Mandatory,Position=1)] - [String]$Operation, - [Parameter(Mandatory,Position=2)] - [String]$Description, - [switch]$Quiet, - [Parameter(ValueFromRemainingArguments,Position=3)] - $more_args -) - $log = $LogTrail.NewLogEntry( - $Operation, - $Description, - $Quiet - ) - try { - Invoke-Command -ScriptBlock $Action -ArgumentList @( - $log, $Quiet, $more_args - ) -ErrorAction Stop - } catch { - $local:Err = $_ - - $local:formatstring = "ERROR: {0} : {1}`n {2}`n" + - " + CategoryInfo : {3}`n" + - " + FullyQualifiedErrorId : {4}`n" + - " + Invoke-LoggedAction args: {5}`n" - - $local:fields = $Err.InvocationInfo.MyCommand.Name, - (@($Err.ErrorDetails, $Err.Exception) | Where-Object {$_.Message} | Select-Object -First 1 -ExpandProperty Message), - $Err.ScriptStackTrace, - $Err.CategoryInfo.ToString(), - $Err.FullyQualifiedErrorId, - ($more_args -join ', ') - - $log = $log.UpdateLogEntry($true,($formatstring -f $fields),$Quiet) - - throw $Err - } finally { - if( $log.Active ) { - $log.UpdateLogEntry($true,"",$Quiet) - } - } -} - -# Initial tests -# Create the group if it does not already exist. -# Iterate through the list of users, for each -# If the user doesn't exist, it will create the user. -# If the user isn't a member of the above mentioned group, add it to it. -# Display a report. -$script:Domain="unknown" - -$Automation = @( - [ordered]@{ - Operation="Get-Command Get-MgContext" - Description="Checking Microsoft.Graph Module command is available" - Action={param([LogEntry]$log,$Quiet) - $null = Get-Command Get-MgContext -ErrorAction Stop - $log.UpdateLogEntry($true,"Success",$Quiet) - } - }, - [ordered]@{ - Operation="Get-MgOrganization" - Description="Testing connection to Microsoft.Graph" - Action={param([LogEntry]$log,$Quiet) - $org = Get-MgOrganization - $script:Domain = $org.VerifiedDomains | - Where-Object IsDefault | - Select-Object -ExpandProperty Name - $log.UpdateLogEntry( - $true, - "Connected to $($org.DisplayName) on $Domain", - $Quiet - ) - } - }, - [ordered]@{ - Operation="Create Group" - Description="Varonis Assignment Group" - Action={param([LogEntry]$log,$Quiet) - $Group = Get-MgGroup -Filter "DisplayName eq 'Varonis Assignment Group'" - if( $Group ) { - $log.UpdateLogEntry($true, "Group already exists $($Group.Id)", $Quiet ) - } else { - $NewGroup = @{ - DisplayName = "Varonis Assignment Group" - Description = "Varonis Assignment Group" - GroupTypes = @() - MailNickname = 'vrns-assign-grp' - MailEnabled = $false - SecurityEnabled = $true - } - $Group = New-MgGroup @NewGroup -ErrorAction Stop - $log.UpdateLogEntry($true, "Group Created $($Group.Id)", $Quiet ) - } - } - } -) - -function Main{ - foreach( $local:Action in $Automation ) { - Invoke-LoggedAction @Action -Quiet -ErrorAction Stop - } - $Group = Get-MgGroup -Filter "DisplayName eq 'Varonis Assignment Group'" - - foreach( $local:i in @(1..20) ) { - $local:UserName = "Test User {0:D2}" -f $i - try { - $local:CreateNewUserAction = @{ - Operation="Create User" - Description="$UserName" - Action={param([LogEntry]$log,$Quiet,$more) - $UserName=$more[0] - $local:User = Get-MgUser -Filter "DisplayName eq '$UserName'" - - if( $User ) { - $log.UpdateLogEntry($true, "User '$UserName' already exists $($User.Id)", $Quiet ) - } else { - $NewUser = @{ - AccountEnabled = $true - DisplayName = $UserName - MailNickname = $UserName -replace ' ','.' - UserPrincipalName = "$($UserName -replace ' ','.')@$script:Domain" - PasswordProfile = @{ - ForceChangePasswordNextSignIn = $true - Password = "MyP@ssw0rd!" - } - } - - # Create the user - $User = New-MgUser @NewUser -ErrorAction Stop - $log.UpdateLogEntry($true, "User '$UserName' created $($User.Id)", $Quiet ) - } - - $User - } - } - $local:User = Invoke-LoggedAction @CreateNewUserAction $UserName -Quiet - - $local:AddUserToGroup = @{ - Operation="Add User to Group: $($Group.DisplayName)" - Description="$UserName" - Action={param([LogEntry]$log,$Quiet,$more) - $Group=$more[0] - $User=$more[1] - $UserName = $User.DisplayName - $GroupName = $Group.DisplayName - - $Groups = Get-MgUserMemberOf -UserId $User.Id | Where-Object Id -eq $Group.Id - - if( $Groups ) { - $log.UpdateLogEntry($true, "User '$UserName' already a member of $GroupName", $Quiet ) - } else { - $AssignGroupMember = @{ - GroupId=$Group.Id - DirectoryObjectId=$User.Id - } - - # Create the user - $User = New-MgGroupMember @AssignGroupMember -ErrorAction Stop - $log.UpdateLogEntry($true, "Success", $Quiet ) - } - } - } - Invoke-LoggedAction @AddUserToGroup $Group $User $User.Id $User.DisplayName -Quiet - } catch { - # In case of error, continue to the next user. - } - } -} - -try { - Main -} catch { - # We are relying on the LogTrail to show us any problems. -} -finally { - Write-Host -ForegroundColor Cyan "Run complete, reprinting complete log:" - $LogTrail.logs | Format-Table -Wrap +# establish Logging mechanism + +class LogEntry { + [bool]$Active=$true + [DateTime]$Timestamp + [string]$Operation + [string]$Description + [TimeSpan]$Duration + [String]$Status + + LogEntry( + [String]$Operation, + [String]$Description, + [switch]$Closed=$false + ){ + if( $Closed ) { $this.Active=$false } + $this.Timestamp=[DateTime]::Now + $this.Operation=$Operation + $this.Description=$Description + $this.Duration=[TimeSpan]::Zero + $this.Status="Open" + } + + [LogEntry]UpdateLogEntry( + [Switch]$Close, + [String]$Status, + [switch]$Quiet + ){ + if( $Close ) { + $this.Active = $false + } + $this.Duration = [DateTime]::Now - $this.Timestamp + if($Status) { $this.Status = $Status } + + if( -not $Quiet ) { + Write-Host -ForegroundColor Gray "Update " -NoNewline + Write-Host "$($this.Operation)/$($this.Description), $($this.Status)" + } + + return $this; + } +} + +class LogTrail { + [System.Collections.Generic.List[LogEntry]]$logs + + LogTrail(){ + $this.logs = [System.Collections.Generic.List[LogEntry]]::new() + } + + [LogEntry]NewLogEntry( + [LogEntry]$LogEntry, + [switch]$Quiet=$false + ){ + if( -not $Quiet ) { + Write-Host -ForegroundColor Cyan "Starting " -NoNewline + Write-Host "$($LogEntry.Operation) / $($LogEntry.Description)..." + } + $this.logs.Add($LogEntry) + return $LogEntry + } + + [LogEntry]NewLogEntry( + [String]$Operation, + [String]$Description, + [bool]$Quiet=$false + ){ + return $this.NewLogEntry( + [LogEntry]::new( + $Operation,$Description,$false + ) + ,$Quiet + ) + } + [LogEntry]NewLogEntry( + [String]$Operation, + [String]$Description + ){ + return $this.NewLogEntry( + $Operation, + $Description, + $false + ) + } + + [LogEntry]NewClosedLogEntry( + [String]$Operation, + [String]$Description, + [switch]$Quiet=$false + ){ + return $this.NewLogEntry( + [LogEntry]::new( + $Operation,$Description,$false + ) + ,$Quiet + ) + } +} +$script:LogTrail = [LogTrail]::new() + +function Invoke-LoggedAction{ +[CmdletBinding()]param( + [Parameter(Mandatory,Position=0)] + [scriptblock]$Action, + [Parameter(Mandatory,Position=1)] + [String]$Operation, + [Parameter(Mandatory,Position=2)] + [String]$Description, + [switch]$Quiet, + [Parameter(ValueFromRemainingArguments,Position=3)] + $more_args +) + $log = $LogTrail.NewLogEntry( + $Operation, + $Description, + $Quiet + ) + try { + Invoke-Command -ScriptBlock $Action -ArgumentList @( + $log, $Quiet, $more_args + ) -ErrorAction Stop + } catch { + $local:Err = $_ + + $local:formatstring = "ERROR: {0} : {1}`n {2}`n" + + " + CategoryInfo : {3}`n" + + " + FullyQualifiedErrorId : {4}`n" + + " + Invoke-LoggedAction args: {5}`n" + + $local:fields = $Err.InvocationInfo.MyCommand.Name, + (@($Err.ErrorDetails, $Err.Exception) | Where-Object {$_.Message} | Select-Object -First 1 -ExpandProperty Message), + $Err.ScriptStackTrace, + $Err.CategoryInfo.ToString(), + $Err.FullyQualifiedErrorId, + ($more_args -join ', ') + + $log = $log.UpdateLogEntry($true,($formatstring -f $fields),$Quiet) + + throw $Err + } finally { + if( $log.Active ) { + $log.UpdateLogEntry($true,"",$Quiet) + } + } +} + +# Initial tests +# Create the group if it does not already exist. +# Iterate through the list of users, for each +# If the user doesn't exist, it will create the user. +# If the user isn't a member of the above mentioned group, add it to it. +# Display a report. +$script:Domain="unknown" + +$Automation = @( + [ordered]@{ + Operation="Get-Command Get-MgContext" + Description="Checking Microsoft.Graph Module command is available" + Action={param([LogEntry]$log,$Quiet) + $null = Get-Command Get-MgContext -ErrorAction Stop + $log.UpdateLogEntry($true,"Success",$Quiet) + } + }, + [ordered]@{ + Operation="Get-MgOrganization" + Description="Testing connection to Microsoft.Graph" + Action={param([LogEntry]$log,$Quiet) + $org = Get-MgOrganization -ErrorAction Stop + $script:Domain = $org.VerifiedDomains | + Where-Object IsDefault | + Select-Object -ExpandProperty Name + $log.UpdateLogEntry( + $true, + "Connected to $($org.DisplayName) on $Domain", + $Quiet + ) + } + }, + [ordered]@{ + Operation="Create Group" + Description="Varonis Assignment Group" + Action={param([LogEntry]$log,$Quiet) + $Group = Get-MgGroup -Filter "DisplayName eq 'Varonis Assignment Group'" + if( $Group ) { + $log.UpdateLogEntry($true, "Group already exists $($Group.Id)", $Quiet ) + } else { + $NewGroup = @{ + DisplayName = "Varonis Assignment Group" + Description = "Varonis Assignment Group" + GroupTypes = @() + MailNickname = 'vrns-assign-grp' + MailEnabled = $false + SecurityEnabled = $true + } + $Group = New-MgGroup @NewGroup -ErrorAction Stop + $log.UpdateLogEntry($true, "Group Created $($Group.Id)", $Quiet ) + } + } + } +) + +function Main{ + foreach( $local:Action in $Automation ) { + Invoke-LoggedAction @Action -Quiet -ErrorAction Stop + } + $Group = Get-MgGroup -Filter "DisplayName eq 'Varonis Assignment Group'" + + foreach( $local:i in @(1..20) ) { + $local:UserName = "Test User {0:D2}" -f $i + try { + $local:CreateNewUserAction = @{ + Operation="Create User" + Description="$UserName" + Action={param([LogEntry]$log,$Quiet,$more) + $UserName=$more[0] + $local:User = Get-MgUser -Filter "DisplayName eq '$UserName'" + + if( $User ) { + $log.UpdateLogEntry($true, "User '$UserName' already exists $($User.Id)", $Quiet ) + } else { + $NewUser = @{ + AccountEnabled = $true + DisplayName = $UserName + MailNickname = $UserName -replace ' ','.' + UserPrincipalName = "$($UserName -replace ' ','.')@$script:Domain" + PasswordProfile = @{ + ForceChangePasswordNextSignIn = $true + Password = "MyP@ssw0rd!" + } + } + + # Create the user + $User = New-MgUser @NewUser -ErrorAction Stop + $log.UpdateLogEntry($true, "User '$UserName' created $($User.Id)", $Quiet ) + } + + $User + } + } + $local:User = Invoke-LoggedAction @CreateNewUserAction $UserName -Quiet + + $local:AddUserToGroup = @{ + Operation="Add User to Group: $($Group.DisplayName)" + Description="$UserName" + Action={param([LogEntry]$log,$Quiet,$more) + $Group=$more[0] + $User=$more[1] + $UserName = $User.DisplayName + $GroupName = $Group.DisplayName + + $Groups = Get-MgUserMemberOf -UserId $User.Id | Where-Object Id -eq $Group.Id + + if( $Groups ) { + $log.UpdateLogEntry($true, "User '$UserName' already a member of $GroupName", $Quiet ) + } else { + $AssignGroupMember = @{ + GroupId=$Group.Id + DirectoryObjectId=$User.Id + } + + # Create the user + $User = New-MgGroupMember @AssignGroupMember -ErrorAction Stop + $log.UpdateLogEntry($true, "Success", $Quiet ) + } + } + } + Invoke-LoggedAction @AddUserToGroup $Group $User $User.Id $User.DisplayName -Quiet + } catch { + # In case of error, continue to the next user. + } + } +} + +try { + Main +} catch { + # We are relying on the LogTrail to show us any problems. +} +finally { + Write-Host -ForegroundColor Cyan "Run complete, reprinting complete log:" + $LogTrail.logs | Format-Table -Wrap } \ No newline at end of file