|
| 1 | +#requires -version 2 |
| 2 | +<# |
| 3 | +.SYNOPSIS |
| 4 | + Add writes on shared mailbox to Office 35 users, with or without automapping |
| 5 | +
|
| 6 | +.DESCRIPTION |
| 7 | + Add writes on shared mailbox to Office 35 users, with or without automapping |
| 8 | +
|
| 9 | +.INPUTS |
| 10 | + .csv file as defined below |
| 11 | +
|
| 12 | +.OUTPUTS |
| 13 | + Create transcript log file similar to $ScriptDir\[SCRIPTNAME]_[YYYY_MM_DD]_[HHhMMmSSs].log |
| 14 | + Create a list of SUBJECT, similar to $ScriptDir\[SCRIPTNAME]_SUBJECT_[YYYY_MM_DD]_[HHhMMmSSs].csv |
| 15 | + |
| 16 | + |
| 17 | +.NOTES |
| 18 | + Version: 0.2 |
| 19 | + Author: ALBERT Jean-Marc |
| 20 | + Creation Date: 14/09/2017 (DD/MM/YYYY) |
| 21 | + Purpose/Change: 0.1 - 2017.09.14 - ALBERT Jean-Marc - Initial script development |
| 22 | + 0.2 - 2017.09.27 - ALBERT Jean-Marc - Verify if started as admin |
| 23 | + |
| 24 | + |
| 25 | +.SOURCES |
| 26 | + <None> |
| 27 | + |
| 28 | + |
| 29 | +.EXAMPLE |
| 30 | + <None> |
| 31 | +
|
| 32 | +#> |
| 33 | + |
| 34 | +#region ---------------------------------------------------------[Initialisations]-------------------------------------------------------- |
| 35 | +Set-StrictMode -version Latest |
| 36 | + |
| 37 | +#Set Error Action to Silently Continue |
| 38 | +$ErrorActionPreference = "SilentlyContinue" |
| 39 | + |
| 40 | +$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition |
| 41 | +$scriptFile = $MyInvocation.MyCommand.Definition |
| 42 | +$launchDate = get-date -f "yyyy.MM.dd-HHhmmmss" |
| 43 | +$logDirectoryPath = $scriptPath + "\" + $launchDate |
| 44 | +$buffer = "$scriptPath\bufferCommand.txt" |
| 45 | +$fullScriptPath = (Resolve-Path -Path $buffer).Path |
| 46 | + |
| 47 | +Add-Type -AssemblyName System.Windows.Forms |
| 48 | +#endregion |
| 49 | + |
| 50 | +#region ----------------------------------------------------------[Declarations]---------------------------------------------------------- |
| 51 | + |
| 52 | +$scriptName = [System.IO.Path]::GetFileName($scriptFile) |
| 53 | +$scriptVersion = "0.2" |
| 54 | + |
| 55 | +if(!(Test-Path $logDirectoryPath)) { |
| 56 | + New-Item $logDirectoryPath -type directory | Out-Null |
| 57 | +} |
| 58 | + |
| 59 | +$logFileName = "Log_" + $launchDate + ".log" |
| 60 | +$logPathName = "$logDirectoryPath\$logFileName" |
| 61 | + |
| 62 | +$global:streamWriter = New-Object System.IO.StreamWriter $logPathName |
| 63 | + |
| 64 | +#endregion |
| 65 | + |
| 66 | +#region -----------------------------------------------------------[Functions]------------------------------------------------------------ |
| 67 | + |
| 68 | +Function Test-IsAdmin { |
| 69 | +<# |
| 70 | +.SYNOPSIS |
| 71 | + Function used to detect if current user is an Administrator. |
| 72 | + |
| 73 | +.DESCRIPTION |
| 74 | + Function used to detect if current user is an Administrator. Presents a menu if not an Administrator |
| 75 | + |
| 76 | +.NOTES |
| 77 | + Name: Test-IsAdmin |
| 78 | + Author: Boe Prox |
| 79 | + DateCreated: 30April2011 |
| 80 | + |
| 81 | +.EXAMPLE |
| 82 | + Test-IsAdmin |
| 83 | + |
| 84 | + |
| 85 | +Description |
| 86 | +----------- |
| 87 | +Command will check the current user to see if an Administrator. If not, a menu is presented to the user to either |
| 88 | +continue as the current user context or enter alternate credentials to use. If alternate credentials are used, then |
| 89 | +the [System.Management.Automation.PSCredential] object is returned by the function. |
| 90 | +#> |
| 91 | + [cmdletbinding()] |
| 92 | + Param() |
| 93 | + |
| 94 | + Write-Verbose "Checking to see if current user context is Administrator" |
| 95 | + If (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) |
| 96 | + { |
| 97 | + Write-Warning "You are not currently running this under an Administrator account! `nThere is potential that this command could fail if not running under an Administrator account." |
| 98 | + Write-Verbose "Presenting option for user to pick whether to continue as current user or use alternate credentials" |
| 99 | + #Determine Values for Choice |
| 100 | + $choice = [System.Management.Automation.Host.ChoiceDescription[]] @("Use &Alternate Credentials","&Continue with current Credentials") |
| 101 | + |
| 102 | + #Determine Default Selection |
| 103 | + [int]$default = 0 |
| 104 | + |
| 105 | + #Present choice option to user |
| 106 | + $userchoice = $host.ui.PromptforChoice("Warning","Please select to use Alternate Credentials or current credentials to run command",$choice,$default) |
| 107 | + |
| 108 | + Write-Debug "Selection: $userchoice" |
| 109 | + |
| 110 | + #Determine action to take |
| 111 | + Switch ($Userchoice) |
| 112 | + { |
| 113 | + 0 |
| 114 | + { |
| 115 | + #Prompt for alternate credentials |
| 116 | + Write-Verbose "Prompting for Alternate Credentials" |
| 117 | + $Credential = Get-Credential |
| 118 | + Write-Output $Credential |
| 119 | + } |
| 120 | + 1 |
| 121 | + { |
| 122 | + #Continue using current credentials |
| 123 | + Write-Verbose "Using current credentials" |
| 124 | + Write-Output "CurrentUser" |
| 125 | + } |
| 126 | + } |
| 127 | + |
| 128 | + } |
| 129 | + Else |
| 130 | + { |
| 131 | + Write-Verbose "Passed Administrator check" |
| 132 | + } |
| 133 | +} |
| 134 | + |
| 135 | +Function Hide-PowershellConsole() { |
| 136 | + # Hide the powershell console window without hiding the other child windows that it spawns. (I.E. hide the powershell window, but not the Out-Gridview window) |
| 137 | + # https://community.spiceworks.com/topic/1710213-hide-a-powershell-console-window-when-running-a-script |
| 138 | + $Script:showWindowAsync = Add-Type -MemberDefinition @" |
| 139 | +[DllImport("user32.dll")] |
| 140 | +public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); |
| 141 | +"@ -Name "Win32ShowWindowAsync" -Namespace Win32Functions -PassThru |
| 142 | + |
| 143 | + $null = $showWindowAsync::ShowWindowAsync((Get-Process -Id $pid).MainWindowHandle, 2) |
| 144 | +} |
| 145 | + |
| 146 | +Function Start-Log { |
| 147 | + [CmdletBinding()] |
| 148 | + Param ([Parameter(Mandatory=$true)][string]$scriptName, [Parameter(Mandatory=$true)][string]$scriptVersion, |
| 149 | + [Parameter(Mandatory=$true)][string]$streamWriter) |
| 150 | + Process{ |
| 151 | + $global:streamWriter.WriteLine("================================================================================================") |
| 152 | + $global:streamWriter.WriteLine("[$ScriptName] version [$ScriptVersion] started at $([DateTime]::Now)") |
| 153 | + $global:streamWriter.WriteLine("================================================================================================`n") |
| 154 | + } |
| 155 | +} |
| 156 | + |
| 157 | +Function Write-Log { |
| 158 | + [CmdletBinding()] |
| 159 | + Param ([Parameter(Mandatory=$true)][string]$streamWriter, [Parameter(Mandatory=$true)][string]$infoToLog) |
| 160 | + Process{ |
| 161 | + $InfoMessage = "$([DateTime]::Now) [INFO] $infoToLog" |
| 162 | + $global:streamWriter.WriteLine($InfoMessage) |
| 163 | + Write-Host $InfoMessage -ForegroundColor Cyan |
| 164 | + } |
| 165 | +} |
| 166 | + |
| 167 | +Function Write-Error { |
| 168 | + [CmdletBinding()] |
| 169 | + Param ([Parameter(Mandatory=$true)][string]$streamWriter, [Parameter(Mandatory=$true)][string]$errorCaught, [Parameter(Mandatory=$true)][boolean]$forceExit) |
| 170 | + Process{ |
| 171 | + $ErrorMessage = "$([DateTime]::Now) [ERROR] $errorCaught" |
| 172 | + $global:streamWriter.WriteLine($ErrorMessage) |
| 173 | + Write-Host $ErrorMessage -ForegroundColor Red |
| 174 | + if ($forceExit -eq $true){ |
| 175 | + End-Log -streamWriter $global:streamWriter |
| 176 | + break; |
| 177 | + } |
| 178 | + } |
| 179 | +} |
| 180 | + |
| 181 | +Function End-Log { |
| 182 | + [CmdletBinding()] |
| 183 | + Param ([Parameter(Mandatory=$true)][string]$streamWriter) |
| 184 | + Process{ |
| 185 | + $global:streamWriter.WriteLine("`n================================================================================================") |
| 186 | + $global:streamWriter.WriteLine("Script ended at $([DateTime]::Now)") |
| 187 | + $global:streamWriter.WriteLine("================================================================================================") |
| 188 | + |
| 189 | + $global:streamWriter.Close() |
| 190 | + } |
| 191 | +} |
| 192 | + |
| 193 | +Function Invoke-Office365TenantLogon { |
| 194 | + #### Pop-up a dialog for username and request your password |
| 195 | + $cred = Get-Credential |
| 196 | + #### Import the Local Microsoft Online PowerShell Module Cmdlets and Connect to O365 Online |
| 197 | + Import-Module MSOnline |
| 198 | + Connect-MsolService -Credential $cred |
| 199 | + #### Establish an Remote PowerShell Session to Exchange Online |
| 200 | + $msoExchangeURL = “https://ps.outlook.com/powershell/” |
| 201 | + $sessionOption = New-PSSessionOption -SkipRevocationCheck #Avoid Certificate error (https://support.microsoft.com/fr-fr/help/2792168/-ssl-certificate-could-not-be-checked-for-revocation-error-when-you-co) |
| 202 | + $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $msoExchangeURL -Credential $cred -Authentication Basic -AllowRedirection -SessionOption $sessionOption |
| 203 | + |
| 204 | + if (!$session) { |
| 205 | + Write-Error -Message 'Opération annulée' |
| 206 | + [Windows.Forms.MessageBox]::Show("Le script n'est pas en mesure de continuer, sans doute à cause de mauvaises informations d'identification. Opération stoppée.", 'Opération stoppée', 0, [Windows.Forms.MessageBoxIcon]::Error) |
| 207 | + Stop-TranscriptOnLog |
| 208 | + Exit |
| 209 | + } |
| 210 | + Else { |
| 211 | + Import-PSSession $session -AllowClobber |
| 212 | + } |
| 213 | + |
| 214 | + } |
| 215 | + |
| 216 | +Function Invoke-Office365TenantLogoff { |
| 217 | + #### Remove the Remote PowerShell Session to Exchange Online ---- |
| 218 | + Get-PsSession | Remove-PsSession |
| 219 | + #Remove-PsSession $session |
| 220 | +} |
| 221 | + |
| 222 | +Function Select-FileDialog { |
| 223 | + [CmdletBinding()] |
| 224 | + param ([string]$Title, |
| 225 | + [string]$Filter = 'All files *.*|*.*') |
| 226 | + Add-Type -AssemblyName System.Windows.Forms | Out-Null |
| 227 | + $fileDialogBox = New-Object -TypeName Windows.Forms.OpenFileDialog |
| 228 | + $fileDialogBox.ShowHelp = $false |
| 229 | + $fileDialogBox.initialDirectory = $scriptPath |
| 230 | + $fileDialogBox.filter = $Filter |
| 231 | + $fileDialogBox.Title = $Title |
| 232 | + $Show = $fileDialogBox.ShowDialog() |
| 233 | + |
| 234 | + if ($Show -eq 'OK') |
| 235 | + { |
| 236 | + Return $fileDialogBox.FileName |
| 237 | + } |
| 238 | + Else |
| 239 | + { |
| 240 | + Write-Error -Message 'Opération annulée' |
| 241 | + [Windows.Forms.MessageBox]::Show("Le script n'est pas en mesure de continuer. Opération stoppée.", 'Opération stoppée', 0, [Windows.Forms.MessageBoxIcon]::Error) |
| 242 | + Stop-TranscriptOnLog |
| 243 | + Exit |
| 244 | + } |
| 245 | +} |
| 246 | + |
| 247 | +Function Stop-Script () { |
| 248 | + Begin{ |
| 249 | + Write-Log -streamWriter $global:streamWriter -infoToLog '--- Script terminating ---' |
| 250 | + } |
| 251 | + Process{ |
| 252 | + 'Script terminating...' |
| 253 | + Write-Verbose -Message '================================================================================================' |
| 254 | + End-Log -streamWriter $global:streamWriter |
| 255 | + Exit |
| 256 | + } |
| 257 | +} |
| 258 | +#endregion |
| 259 | + |
| 260 | +#region ----------------------------------------------------------[Execution]---------------------------------------------------------- |
| 261 | + |
| 262 | +# Check if Admin |
| 263 | +$admincheck = Test-IsAdmin |
| 264 | + If ($admincheck -is [System.Management.Automation.PSCredential]) { |
| 265 | + Write-Error -Message 'Opération annulée' |
| 266 | + Start-Process -FilePath PowerShell.exe -Credential $admincheck -ArgumentList $myinvocation.mycommand.definition |
| 267 | + Break |
| 268 | + } |
| 269 | + |
| 270 | +# Start log creation and completion |
| 271 | +Start-Log -scriptName $scriptName -scriptVersion $scriptVersion -streamWriter $global:streamWriter |
| 272 | + |
| 273 | +# Disclaimer |
| 274 | +$Disclaimer = [Windows.Forms.MessageBox]::Show( |
| 275 | + " |
| 276 | +Ce script a pour but de déléguer des droits sur une boîte partagée. |
| 277 | +Pour cela, il injecte des données venant d'un fichier .csv directement sur Office 365. |
| 278 | +
|
| 279 | +
|
| 280 | + /!\ Attention /!\ |
| 281 | +
|
| 282 | +Si vous n'êtes pas sûr des actions à mener, ou de l'impact sur la messagerie, quitter ce script dès à présent. |
| 283 | +
|
| 284 | +Souhaitez-vous continuer ? |
| 285 | +
|
| 286 | +
|
| 287 | +", 'Boîte partagée', 1, [Windows.Forms.MessageBoxIcon]::Question) |
| 288 | +If ($Disclaimer -eq "OK") |
| 289 | +{ |
| 290 | + Write-Information 'Patientez, traitement en cours ...' |
| 291 | +} |
| 292 | +Else |
| 293 | +{ |
| 294 | + Write-Error -Message 'Opération annulée' |
| 295 | + [Windows.Forms.MessageBox]::Show("Le script n'est pas en mesure de continuer. Opération stoppée.", 'Opération stoppée', 0, [Windows.Forms.MessageBoxIcon]::Error) |
| 296 | + Stop-TranscriptOnLog |
| 297 | + Exit |
| 298 | +} |
| 299 | + |
| 300 | +# Start a connection to Office 365 |
| 301 | +Invoke-Office365TenantLogon |
| 302 | + |
| 303 | +# Import CSV file |
| 304 | +[Windows.Forms.MessageBox]::Show( |
| 305 | + " |
| 306 | +Sélectionner dans cette fenêtre le fichier contenant : |
| 307 | + - L'adresse e-mail du nom de l'utilisateur à attacher à une boîte partagée |
| 308 | + - Le nom de la boîte partagée concernée |
| 309 | + - Si la boîte partagée doit s'automonter (mapping) |
| 310 | +
|
| 311 | +Le fichier doit être de la forme suivante : |
| 312 | +
|
| 313 | +UserEmailAddress SharedboxName SendAs Automapping |
| 314 | +john.doe@dom.com Production Yes No |
| 315 | +jane.roe@dom.com Production No Yes |
| 316 | +
|
| 317 | +", 'Shared mailbox', 0, [Windows.Forms.MessageBoxIcon]::Question) |
| 318 | + |
| 319 | +# Import list of users and related sharedmailbox and rights |
| 320 | +$CSVInputFile = Select-FileDialog -Title 'Select CSV file' -Filter 'Fichier CSV (*.csv) |*.csv' |
| 321 | +$csvValues = Import-Csv $CSVInputFile -Delimiter ';' |
| 322 | +Write-Log -streamWriter $global:streamWriter -infoToLog Fichier source sélectionné : $CSVInputFile |
| 323 | + |
| 324 | +# Set parameter for delegation with a loop |
| 325 | +foreach ($line in $csvValues) |
| 326 | +{ |
| 327 | + $UserEmailAddress = $line.UserEmailAddress |
| 328 | + $SharedboxName = $line.SharedboxName |
| 329 | + $SendAs = $line.SendAs |
| 330 | + $Automapping = $line.Automapping |
| 331 | + switch ($SendAs) |
| 332 | + { |
| 333 | + 'Oui' { $SendAs = 'Yes' } |
| 334 | + 'Non' { $SendAs = 'No' } |
| 335 | + default { $SendAs = $false } |
| 336 | + } |
| 337 | + switch ($Automapping) |
| 338 | + { |
| 339 | + 'Oui' { $Automapping = $true } |
| 340 | + 'Non' { $Automapping = $false } |
| 341 | + default { $Automapping = $true } |
| 342 | + } |
| 343 | + |
| 344 | + Write-Host $UserEmailAddress $SharedboxName $SendAs $Automapping |
| 345 | + Write-Log -streamWriter $global:streamWriter -infoToLog $UserEmailAddress $SharedboxName $SendAs $Automapping |
| 346 | + |
| 347 | + #Adding users to the shared mailbox is a two-step process. First, we'll need to give the user access to the mailbox |
| 348 | + Add-MailboxPermission -Identity $SharedboxName -AccessRights 'FullAccess' -InheritanceType All -AutoMapping:$Automapping -User $UserEmailAddress |
| 349 | + |
| 350 | + if ($SendAs -eq 'Yes') |
| 351 | + { |
| 352 | + #Give the end user permission to send as the account |
| 353 | + Add-RecipientPermission -Identity $SharedboxName -AccessRights SendAs -Confirm:$false -Trustee $UserEmailAddress |
| 354 | + } |
| 355 | +} |
| 356 | + |
| 357 | + |
| 358 | +# Success message |
| 359 | +[Windows.Forms.MessageBox]::Show( |
| 360 | + "Action menée avec succès. |
| 361 | +", 'Boîte partagée', 0, [Windows.Forms.MessageBoxIcon]::Information) |
| 362 | +Write-Log -streamWriter $global:streamWriter -infoToLog 'Action menée avec succès.' |
| 363 | + |
| 364 | + |
| 365 | +# Stop the connection to Office 365 |
| 366 | +Invoke-Office365TenantLogoff |
| 367 | +Write-Log -streamWriter $global:streamWriter -infoToLog "Déconnexion de l'instance Office 365 Tenant" |
| 368 | + |
| 369 | +Stop-Script |
| 370 | +#endregion |
0 commit comments