Skip to content

Commit 044a38b

Browse files
authored
Create Add-UserToSharedMailbox.ps1
1 parent 8f2431c commit 044a38b

1 file changed

Lines changed: 370 additions & 0 deletions

File tree

Lines changed: 370 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,370 @@
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

Comments
 (0)