-
Notifications
You must be signed in to change notification settings - Fork 346
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
FreeBusyChecker Final Version #2264
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,297 @@ | ||
# Copyright (c) Microsoft Corporation. | ||
# Licensed under the MIT License. | ||
<# | ||
.SYNOPSIS | ||
|
||
.\FreeBusyChecker.ps1 | ||
|
||
.DESCRIPTION | ||
|
||
This script can be used to validate the Availability configuration of the following Exchange Server Versions: | ||
|
||
- Exchange Server | ||
- Exchange Online | ||
|
||
Required Permissions: | ||
|
||
- Organization Management | ||
- Domain Admin | ||
|
||
Please make sure that the account used is a member of the Local Administrator group. This should be fulfilled on Exchange Servers by being a member of the Organization Management group. However, if the group membership was adjusted, or in case the script is executed on a non-Exchange system like a management Server, you need to add your account to the Local Administrator group. | ||
|
||
How To Run: | ||
|
||
This script must be run as Administrator in Exchange Management Shell on an Exchange Server. You can provide no parameters, and the script will just run against Exchange On-Premises and Exchange Online to query for OAuth and DAuth configuration settings. It will compare existing values with standard values and provide details of what may not be correct. | ||
Please take note that though this script may output that a specific setting is not a standard setting, it does not mean that your configurations are incorrect. For example, DNS may be configured with specific mappings that this script cannot evaluate. | ||
|
||
To collect information for Exchange Online a connection to Exchange Online must be established before running the script using Connection Prefix "EO". | ||
|
||
Example: | ||
|
||
PS C:\scripts\FreeBusyChecker> Connect-ExchangeOnline -Prefix EO | ||
|
||
.PARAMETER Auth | ||
Allows you to choose the authentication type to validate. | ||
.PARAMETER Org | ||
Allows you to choose the organization type to validate. | ||
.PARAMETER OnPremUser | ||
Specifies the Exchange On Premise User that will be used to test Free Busy Settings. | ||
.PARAMETER OnlineUser | ||
Specifies the Exchange Online User that will be used to test Free Busy Settings. | ||
.PARAMETER OnPremDomain | ||
Specifies the domain for on-premises Organization. | ||
.PARAMETER OnPremEWSUrl | ||
Specifies the EWS (Exchange Web Services) URL for on-premises Exchange Server. | ||
.PARAMETER OnPremLocalDomain | ||
Specifies the local AD domain for the on-premises Organization. | ||
.PARAMETER Help | ||
Show help for this script. | ||
|
||
.EXAMPLE | ||
.\FreeBusyChecker.ps1 | ||
This cmdlet will run the Free Busy Checker script and Check Availability OAuth and DAuth Configurations both for Exchange On-Premises and Exchange Online. | ||
.EXAMPLE | ||
.\FreeBusyChecker.ps1 -Auth OAuth | ||
This cmdlet will run the Free Busy Checker Script against OAuth Availability Configurations. | ||
.EXAMPLE | ||
.\FreeBusyChecker.ps1 -Auth DAuth | ||
This cmdlet will run the Free Busy Checker Script against DAuth Availability Configurations. | ||
.EXAMPLE | ||
.\FreeBusyChecker.ps1 -Org ExchangeOnline | ||
This cmdlet will run the Free Busy Checker Script for Exchange Online Availability Configurations. | ||
.EXAMPLE | ||
.\FreeBusyChecker.ps1 -Org ExchangeOnPremise | ||
This cmdlet will run the Free Busy Checker Script for Exchange On-Premises OAuth or DAuth Availability Configurations. | ||
.EXAMPLE | ||
.\FreeBusyChecker.ps1 -Org All | ||
This cmdlet will run the Free Busy Checker Script for Exchange On-Premises and Exchange Online OAuth or DAuth Availability Configurations. | ||
.EXAMPLE | ||
.\FreeBusyChecker.ps1 -Org ExchangeOnPremise -Auth OAuth | ||
This cmdlet will run the Free Busy Checker Script for Exchange On-Premises Availability OAuth Configurations | ||
#> | ||
|
||
# Exchange On-Premises | ||
#> | ||
#region Properties and Parameters | ||
|
||
#Requires -Module ExchangeOnlineManagement | ||
#Requires -Module ActiveDirectory | ||
|
||
[CmdletBinding(DefaultParameterSetName = "FreeBusyInfo_OP", SupportsShouldProcess)] | ||
|
||
param( | ||
[Parameter(Mandatory = $false, ParameterSetName = "Test")] | ||
[ValidateSet('DAuth', 'OAuth', 'All', '')] | ||
[string[]]$Auth, | ||
[Parameter(Mandatory = $false, ParameterSetName = "Test")] | ||
[ValidateSet('ExchangeOnPremise', 'ExchangeOnline')] | ||
[string[]]$Org, | ||
[Parameter(Mandatory = $true, ParameterSetName = "Help")] | ||
[switch]$Help, | ||
[Parameter(Mandatory = $false, ParameterSetName = "Test")] | ||
[string]$OnPremisesUser, | ||
[Parameter(Mandatory = $false, ParameterSetName = "Test")] | ||
[string]$OnlineUser, | ||
[Parameter(Mandatory = $false, ParameterSetName = "Test")] | ||
[string]$OnPremDomain, | ||
[Parameter(Mandatory = $false, ParameterSetName = "Test")] | ||
[string]$OnPremEWSUrl, | ||
[Parameter(Mandatory = $false, ParameterSetName = "Test")] | ||
[string]$OnPremLocalDomain, | ||
[Parameter(Mandatory = $true, ParameterSetName = "ScriptUpdateOnly", HelpMessage = "Update only script.")] | ||
[switch]$ScriptUpdateOnly, | ||
[Parameter(Mandatory = $false, ParameterSetName = "SkipVersionCheck", HelpMessage = "Skip version check.")] | ||
[switch]$SkipVersionCheck | ||
) | ||
begin { | ||
. $PSScriptRoot\Functions\OnPremDAuthFunctions.ps1 | ||
. $PSScriptRoot\Functions\OnPremOAuthFunctions.ps1 | ||
. $PSScriptRoot\Functions\ExoDAuthFunctions.ps1 | ||
. $PSScriptRoot\Functions\ExoOAuthFunctions.ps1 | ||
. $PSScriptRoot\Functions\htmlContent.ps1 | ||
. $PSScriptRoot\Functions\hostOutput.ps1 | ||
. $PSScriptRoot\Functions\CommonFunctions.ps1 | ||
. $PSScriptRoot\..\..\Shared\Confirm-ExchangeShell.ps1 | ||
. $PSScriptRoot\..\..\Shared\ScriptUpdateFunctions\GenericScriptUpdate.ps1 | ||
} end { | ||
$Script:countOrgRelIssues = (0) | ||
$Script:WebServicesVirtualDirectory = $null | ||
$Script:Server = hostname | ||
$Script:startingDate = (Get-Date -Format yyyyMMdd_HHmmss) | ||
$Script:htmlFile = "$PSScriptRoot\FBCheckerOutput_$($Script:startingDate).html" | ||
|
||
loadingParameters | ||
#Parameter input | ||
|
||
if (-not $OnlineUser) { | ||
$Script:UserOnline = Get-RemoteMailbox -ResultSize 1 -WarningAction SilentlyContinue | ||
$Script:UserOnline = $Script:UserOnline.RemoteRoutingAddress.SmtpAddress | ||
} else { | ||
$Script:UserOnline = Get-RemoteMailbox $OnlineUser -ResultSize 1 -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | ||
$Script:UserOnline = $Script:UserOnline.RemoteRoutingAddress.SmtpAddress | ||
} | ||
|
||
$Script:ExchangeOnlineDomain = ($Script:UserOnline -split "@")[1] | ||
|
||
if ($Script:ExchangeOnlineDomain -like "*.mail.onmicrosoft.com") { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about other cloud? Is the script expected to work on these (e.g., GCC, Gallatin…)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They were not considered at start, I had no reference for this clouds and no way to test. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if this is 100% required before we release. It would be nice yes, but I would rather get something out there and us create an issue for this and address it soon. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's okay to address this with a later update. We should mention in the documentation that the script works with WW cloud only. |
||
$Script:ExchangeOnlineAltDomain = (($Script:ExchangeOnlineDomain.Split(".")))[0] + ".onmicrosoft.com" | ||
} else { | ||
$Script:ExchangeOnlineAltDomain = (($Script:ExchangeOnlineDomain.Split(".")))[0] + ".mail.onmicrosoft.com" | ||
} | ||
$Script:temp = "*" + $Script:ExchangeOnlineDomain | ||
$Script:UserOnPrem = "" | ||
if (-not $OnPremisesUser) { | ||
$Script:UserOnPrem = Get-mailbox -ResultSize 2 -WarningAction SilentlyContinue -Filter 'EmailAddresses -like $temp -and HiddenFromAddressListsEnabled -eq $false' -ErrorAction SilentlyContinue | ||
if ($Script:UserOnPrem) { | ||
$Script:UserOnPrem = $Script:UserOnPrem[1].PrimarySmtpAddress.Address | ||
} | ||
} else { | ||
$Script:UserOnPrem = Get-mailbox $OnPremisesUser -WarningAction SilentlyContinue -Filter 'EmailAddresses -like $temp -and HiddenFromAddressListsEnabled -eq $false' -ErrorAction SilentlyContinue | ||
$Script:UserOnPrem = $Script:UserOnPrem.PrimarySmtpAddress.Address | ||
} | ||
$Script:ExchangeOnPremDomain = ($Script:UserOnPrem -split "@")[1] | ||
|
||
if (-not $OnPremEWSUrl) { | ||
FetchEWSInformation | ||
} else { | ||
FetchEWSInformation | ||
$Script:ExchangeOnPremEWS = ($OnPremEWSUrl) | ||
} | ||
|
||
if (-not $OnPremDomain) { | ||
$ADDomain = Get-ADDomain | ||
$Script:ExchangeOnPremLocalDomain = $ADDomain.forest | ||
} else { | ||
$Script:ExchangeOnPremLocalDomain = $OnPremDomain | ||
} | ||
|
||
$Script:ExchangeOnPremLocalDomain = $ADDomain.forest | ||
if ([string]::IsNullOrWhitespace($ADDomain)) { | ||
$Script:ExchangeOnPremLocalDomain = $exchangeOnPremDomain | ||
} | ||
|
||
if ($ExchangeOnPremDomain) { | ||
$Script:FedInfoEOP = Get-federationInformation -DomainName $ExchangeOnPremDomain -BypassAdditionalDomainValidation -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Select-Object * | ||
} | ||
#endregion | ||
|
||
if ($Help) { | ||
PrintDynamicWidthLine | ||
ShowHelp | ||
PrintDynamicWidthLine | ||
exit | ||
} | ||
#region Show Parameters | ||
$Script:IntraOrgCon = Get-IntraOrganizationConnector -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Where-Object { $_.TargetAddressDomains -contains $Script:ExchangeOnlineDomain } | Select-Object Name, TarGetAddressDomains, DiscoveryEndpoint, Enabled | ||
ShowParameters | ||
CheckParameters | ||
if ($Script:IntraOrgCon.enabled -eq $true) { | ||
$Auth = hostOutputIntraOrgConEnabled($Auth) | ||
} | ||
if ($Script:IntraOrgCon.enabled -eq $false) { | ||
hostOutputIntraOrgConNotEnabled | ||
} | ||
# Free busy Lookup methods | ||
PrintDynamicWidthLine | ||
$Script:OrgRel = Get-OrganizationRelationship | Where-Object { ($_.DomainNames -like $Script:ExchangeOnlineDomain) } -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Select-Object Enabled, Identity, DomainNames, FreeBusy*, TarGet* | ||
$Script:EDiscoveryEndpoint = Get-IntraOrganizationConfiguration -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Select-Object OnPremiseDiscoveryEndpoint | ||
$Script:SPDomainsOnprem = Get-SharingPolicy -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Format-List Domains | ||
$Script:SPOnprem = Get-SharingPolicy -WarningAction SilentlyContinue -ErrorAction SilentlyContinue | Select-Object * | ||
|
||
if ($Org -contains 'ExchangeOnPremise' -or -not $Org) { | ||
#region DAuth Checks | ||
if ($Auth -like "DAuth" -or -not $Auth -or $Auth -like "All") { | ||
Write-Host " Testing DAuth Configuration" | ||
OrgRelCheck -OrgRelParameter $Script:OrgRel | ||
PrintDynamicWidthLine | ||
FedInfoCheck | ||
FedTrustCheck | ||
AutoDVirtualDCheck | ||
PrintDynamicWidthLine | ||
EWSVirtualDirectoryCheck | ||
AvailabilityAddressSpaceCheck | ||
TestFedTrust | ||
TestOrgRel | ||
} | ||
#endregion | ||
#region OAuth Check | ||
if ($Auth -like "OAuth" -or -not $Auth -or $Auth -like "All") { | ||
Write-Host " Testing OAuth Configuration" | ||
IntraOrgConCheck | ||
PrintDynamicWidthLine | ||
AuthServerCheck | ||
PrintDynamicWidthLine | ||
PartnerApplicationCheck | ||
PrintDynamicWidthLine | ||
ApplicationAccountCheck | ||
PrintDynamicWidthLine | ||
ManagementRoleAssignmentCheck | ||
PrintDynamicWidthLine | ||
AuthConfigCheck | ||
PrintDynamicWidthLine | ||
CurrentCertificateThumbprintCheck | ||
PrintDynamicWidthLine | ||
AutoDVirtualDCheckOAuth | ||
PrintDynamicWidthLine | ||
EWSVirtualDirectoryCheckOAuth | ||
PrintDynamicWidthLine | ||
AvailabilityAddressSpaceCheckOAuth | ||
PrintDynamicWidthLine | ||
OAuthConnectivityCheck | ||
PrintDynamicWidthLine | ||
} | ||
#endregion | ||
} | ||
# EXO Part | ||
if ($Org -contains 'ExchangeOnline' -or -not $Org) { | ||
#region ConnectExo | ||
$Exo = Test-ExchangeOnlineConnection | ||
if (-not ($Exo)) { | ||
Write-Host -ForegroundColor Red "`n Please connect to Exchange Online Using the EXO V3 module using EO as connection Prefix to collect Exchange OnLine Free Busy configuration Information." | ||
Write-Host -ForegroundColor Cyan "`n`n Example: PS C:\Connect-ExchangeOnline -Prefix EO" | ||
Write-Host -ForegroundColor Yellow "`n More Info at:https://learn.microsoft.com/en-us/powershell/exchange/exchange-online-powershell-v2?view=exchange-ps" | ||
exit | ||
} | ||
Write-Host " Connected to Exchange Online." | ||
$Script:ExoOrgRel = Get-EOOrganizationRelationship | Where-Object { ($_.DomainNames -like $ExchangeOnPremDomain ) } | Select-Object Enabled, Identity, DomainNames, FreeBusy*, TarGet* | ||
$Script:ExoIntraOrgCon = Get-EOIntraOrganizationConnector | Select-Object Name, TarGetAddressDomains, DiscoveryEndpoint, Enabled | ||
$Script:tarGetAddressPr1 = ("https://AutoDiscover." + $ExchangeOnPremDomain + "/AutoDiscover/AutoDiscover.svc/WSSecurity") | ||
$Script:tarGetAddressPr2 = ("https://" + $ExchangeOnPremDomain + "/AutoDiscover/AutoDiscover.svc/WSSecurity") | ||
exoHeaderHtml | ||
|
||
#endregion | ||
|
||
#region ExoDAuthCheck | ||
if ($Auth -like "DAuth" -or -not $Auth -or $Auth -like "All") { | ||
PrintDynamicWidthLine | ||
Write-Host $TestingExoDAuthConfiguration | ||
ExoOrgRelCheck | ||
PrintDynamicWidthLine | ||
ExoFedOrgIdCheck | ||
PrintDynamicWidthLine | ||
ExoTestOrgRelCheck | ||
SharingPolicyCheck | ||
} | ||
#endregion | ||
|
||
#region ExoOauthCheck | ||
if ($Auth -like "OAuth" -or -not $Auth -or $Auth -like "All") { | ||
Write-Host $TestingExoOAuthConfiguration | ||
ExoIntraOrgConCheck | ||
PrintDynamicWidthLine | ||
EXOIntraOrgConfigCheck | ||
PrintDynamicWidthLine | ||
EXOAuthServerCheck | ||
PrintDynamicWidthLine | ||
ExoTestOAuthCheck | ||
PrintDynamicWidthLine | ||
} | ||
#endregion | ||
|
||
Write-Host -ForegroundColor Green $ThatIsAllForTheExchangeOnlineSide | ||
|
||
PrintDynamicWidthLine | ||
} | ||
|
||
Stop-Transcript | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# Copyright (c) Microsoft Corporation. | ||
# Licensed under the MIT License. | ||
function Test-ExchangeOnlineConnection { | ||
Write-Host -ForegroundColor Green " Checking Exchange Online Configuration" | ||
Write-Host " Testing Connection to Exchange Online with EO Prefix." | ||
try { | ||
$CheckExoMailbox = Get-EOMailbox $Script:UserOnline -ErrorAction Stop | ||
if ($null -ne $CheckExoMailbox) { | ||
return $true | ||
} else { | ||
return $false | ||
} | ||
} catch { | ||
return $false | ||
} | ||
} | ||
function FetchAutoDiscoverInformation { | ||
if (-not $Script:AutoDiscoveryVirtualDirectory -or -not $Script:AutoDiscoveryVirtualDirectoryOAuth) { | ||
$Script:AutoDiscoveryVirtualDirectory = Get-AutoDiscoverVirtualDirectory -Server $Script:Server | Select-Object Identity, Name, ExchangeVersion, *authentication* -ErrorAction SilentlyContinue | ||
$Script:AutoDiscoveryVirtualDirectoryOAuth = $Script:AutoDiscoveryVirtualDirectory | ||
} | ||
} | ||
function FetchEWSInformation { | ||
if (-not $Script:WebServicesVirtualDirectory -or -not $Script:WebServicesVirtualDirectoryOAuth) { | ||
$Script:WebServicesVirtualDirectory = Get-WebServicesVirtualDirectory -Server $Script:Server | Select-Object Identity, Name, ExchangeVersion, *Authentication*, *url -ErrorAction SilentlyContinue | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you, great point! Will do. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -ADPropertiesOnly indeed can't be used Get-WebServicesVirtualDirectory was called multiple times. It is called initially as it is a required Initial Parameter. It was also called on DAuth and Oauth Checks. It was executed 3 times if user inputs -Auth All when calling script: Now it is called only once initially: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, run the cmdlet once and then store it in a script variable or get it with a cmdlet that has it stored within a script variable. |
||
$Script:WebServicesVirtualDirectoryOAuth = $Script:WebServicesVirtualDirectory | ||
$Script:ExchangeOnPremEWS = ($Script:WebServicesVirtualDirectory.externalURL.AbsoluteUri) | ||
} | ||
} | ||
function CheckIfExchangeServer { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd recommend using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
$exchangeShell = Confirm-ExchangeShell | ||
if (-not($exchangeShell.ShellLoaded)) { | ||
Write-Host "$Server is not an Exchange Server. This script should be run in Exchange Server Management Shell" | ||
exit | ||
} | ||
} | ||
function CheckParameters { | ||
$MissingParameters = @() | ||
if ([string]::IsNullOrWhiteSpace($Script:ExchangeOnlineDomain)) { | ||
$MissingParameters += "Exchange Online Domain. Example: contoso.mail.onmicrosoft.com" | ||
} | ||
if ([string]::IsNullOrWhiteSpace($Script:ExchangeOnPremLocalDomain)) { | ||
$MissingParameters += "Exchange On Premises Local Domain. Example: . 'C:\scripts\FreeBusyChecker\FreeBusyChecker.ps1' -OnPremisesUser [email protected]" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be better to do something like this for the example as this will reflect the name of the script (even if it was renamed for whatever reason):
Same for the following examples (line There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As far as I remember it should return the name of the script even if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
if ([string]::IsNullOrWhiteSpace($exchangeOnPremDomain)) { | ||
$MissingParameters += "Exchange On Premises Domain. Example: -OnPremLocalDomain Contoso.local" | ||
} | ||
if ([string]::IsNullOrWhiteSpace($exchangeOnPremEWS)) { | ||
$MissingParameters += "Exchange On Premises EWS Virtual Directory External URL. Example: 'C:\FreeBusyChecker.ps1' -OnPremEWSUrl https://mail.contoso.com/EWS/Exchange.asmx" | ||
} | ||
if ([string]::IsNullOrWhiteSpace($Script:UserOnPrem)) { | ||
$MissingParameters += "On Premises User Mailbox. Example: 'C:\FreeBusyChecker.ps1' -OnPremisesUser [email protected]" | ||
} | ||
if ([string]::IsNullOrWhiteSpace($Script:UserOnline)) { | ||
$MissingParameters += "Exchange Online Mailbox. Example: 'C:\FreeBusyChecker.ps1' -OnlineUser [email protected]" | ||
} | ||
|
||
if ($MissingParameters.Count -gt 0) { | ||
foreach ($param in $MissingParameters) { | ||
Write-Host -ForegroundColor Red "Please provide a value for $param." | ||
} | ||
exit 1 | ||
} | ||
Write-Host -ForegroundColor Cyan "`n All parameters are valid." | ||
return | ||
} |
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.
Can we add
GenericScriptUpdate.ps1
here? This adds update capabilities to the script and allows the script to perform an auto-update whenever a new version is released.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.
Added this:
The version CSV does not hold information about this script. I suppose this message will display Script Name and version when the csv holds this information:
I see implementations with aka url poiting to csv update file. Should I create one?
Can't test this., so not sure if I understood correctly.
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.
It isn't required, but you can put one there.
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.
Ok, i will commit this evening