19 December 2017

Allow workgroup machine to administer Hyper-V server

Got a Windows 10 machine running in a workgroup but want to administer Hyper-V server(s)

Run this in an elevated PowerShell Session:

Set-Item WSMan:\localhost\Client\TrustedHosts -Value '*'



Failed Content Index State - Known Issue KB4045655

After installing KB4045655, the security update for Microsoft Exchange 2013 and 2016 you may encounter failed content index states.

View the status of all database content index:
Get-MailboxDatabaseCopyStatus *

How to recover from this can be done multiple ways, but the question I have is why did this happen in the first place?

Searching through the services list I came across the "Microsoft Exchange Search Host Controller" and it was in a Disabled startup type.
Strange because it needs to be started automatically as it interacts with the "Microsoft Exchange Search" service.

After setting the service to start as automatic began searching why it would set as disabled.

In the link I posted at the top of this post lays the answer.
And I quote:

Known issues


We are aware of some reports that Exchange services may remain in a disabled state after installing this security update.  If this occurs, the update has installed correctly, but the service control script encountered a problem returning Exchange services to a normal state.  To resolve this issue, use Services Manager to restore the startup type to Automatic, and then start the affected Exchange services manually.

So there you have it, and it goes to show that reading the Microsoft documentation and knowledge base articles is a must.

28 November 2017

Increase your OneDrive for Business storage quota to the max of your license

I had never seen this or read about it until now.
Turns out that the default storage quota for a OneDrive for Business user is 1 TB.
This goes for

  • Office 365 Enterprise E3 and E5, 
  • Office 365 Goverment E3 and E5
  • Office 365 Education and Office 365 Education E5
  • OneDrive for Business Plan 2 and SharePoint Online Plan 2
All these licenses are allowed to increase the storage quota to 5 TB.
It doesn't show this when you check in the admin portal.


Only after clicking the link "What's the maximum for my Office 365 plan?" you're taken to a page that states the above.

So how do we take advantage of all this storage space?
I'm mostly interested in the way to set it for one specific user:

First we need to get the OneDrive for Business site url, the easiest way to get this is to click in the Office365 menu tile.
You're taken to your OneDrive for Business site.
Copy the url from the browser, it looks something like this:
https://tenant-my.sharepoint.com/personal/firstname_lastname_domain_com

Then we go to PowerShell and fire up the SharePoint Online PowerShell module.

When logged in we view the current settings:
get-SPOSite -Identity https://tenant-my.sharepoint.com/personal/firstname_lastname_domain_com | select storagequota            
            
StorageQuota            
____________            
     1048576

Now to set the maximum of 5 TB for this one User:
Set-SPOSite -Identity https://tenant-my.sharepoint.com/personal/firstname_lastname_domain_com -StorageQuota 5242880

Check to see the change:
get-SPOSite -Identity https://tenant-my.sharepoint.com/personal/firstname_lastname_domain_com | select storagequota            
            
StorageQuota            
____________            
     5242880

In case there's the need to reset it to the default value:
Set-SPOSite -Identity https://tenant-my.sharepoint.com/personal/firstname_lastname_domain_com -StorageQuotaReset

14 November 2017

Cannot contact web site xxxx-admin.sharepoint.com or the web site does not support SharePoint Online credentials

Trying to pre-provision some OneDrive users on Office365 I came across this error after trying to connect to the Sharepoint site:
PS C:\> .\BulkEnqueueOneDriveSite.ps1 -SPOAdminUrl https://tenant.sharepoint.com -InputFilePath .\UserInput.txt
Please enter a Tenant Admin username
admin@tenant.onmicrosoft.com
Please enter your password
*******************************
Exception calling "ExecuteQuery" with "0" argument(s): "Cannot contact web site 'https://tenant.sharepoint.com/' or the
web site does not support SharePoint Online credentials. The response status code is 'Unauthorized'. The response heade
rs are 'X-SharePointHealthScore=5, X-MSDAVEXT_Error=917656; Access+denied.+Before+opening+files+in+this+location%2c+you
+must+first+browse+to+the+web+site+and+select+the+option+to+login+automatically., SPRequestGuid=b4c82c9e-5087-4000-7c44
-3b884b58ddef, request-id=b4c82c9e-5087-4000-7c44-3b884b58ddef, MS-CV=nizItIdQAEB8RDuIS1jd7w.0, Strict-Transport-Securi
ty=max-age=31536000, X-FRAME-OPTIONS=SAMEORIGIN, SPRequestDuration=113, SPIisLatency=1, MicrosoftSharePointTeamServices
=16.0.0.7108, X-Content-Type-Options=nosniff, X-MS-InvokeApp=1; RequireReadOnly, X-MSEdge-Ref=Ref A: 489B56D95E98428AB2
BF5250B429009B Ref B: AMS04EDGE0606 Ref C: 2017-11-14T11:51:12Z, Content-Length=0, Content-Type=text/plain; charset=utf
-8, Date=Tue, 14 Nov 2017 11:51:11 GMT, P3P=CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo C
NT COM INT NAV ONL PHY PRE PUR UNI", X-Powered-By=ASP.NET'."
At BulkEnqueueOneDriveSite.ps1:67 char:1
+ $ctx.ExecuteQuery()
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NotSupportedException

Exception calling "ExecuteQuery" with "0" argument(s): "Cannot contact web site 'https://tenant.sharepoint.com/' or the
web site does not support SharePoint Online credentials. The response status code is 'Unauthorized'. The response heade
rs are 'X-SharePointHealthScore=6, X-MSDAVEXT_Error=917656; Access+denied.+Before+opening+files+in+this+location%2c+you
+must+first+browse+to+the+web+site+and+select+the+option+to+login+automatically., SPRequestGuid=b4c82c9e-a0a1-4000-7c44
-3e7f7034d943, request-id=b4c82c9e-a0a1-4000-7c44-3e7f7034d943, MS-CV=nizItKGgAEB8RD5/cDTZQw.0, Strict-Transport-Securi
ty=max-age=31536000, X-FRAME-OPTIONS=SAMEORIGIN, SPRequestDuration=158, SPIisLatency=2, MicrosoftSharePointTeamServices
=16.0.0.7108, X-Content-Type-Options=nosniff, X-MS-InvokeApp=1; RequireReadOnly, X-MSEdge-Ref=Ref A: C1ACEE6EF2A74BC1A7
0B6E46B03C3F5E Ref B: AMS04EDGE0606 Ref C: 2017-11-14T11:51:12Z, Content-Length=0, Content-Type=text/plain; charset=utf
-8, Date=Tue, 14 Nov 2017 11:51:11 GMT, P3P=CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo C
NT COM INT NAV ONL PHY PRE PUR UNI", X-Powered-By=ASP.NET'."
At BulkEnqueueOneDriveSite.ps1:70 char:1
+ $ctx.ExecuteQuery()
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NotSupportedException

Exception calling "ExecuteQuery" with "0" argument(s): "Cannot contact web site 'https://tenant.sharepoint.com/' or the
web site does not support SharePoint Online credentials. The response status code is 'Unauthorized'. The response heade
rs are 'X-SharePointHealthScore=5, X-MSDAVEXT_Error=917656; Access+denied.+Before+opening+files+in+this+location%2c+you
+must+first+browse+to+the+web+site+and+select+the+option+to+login+automatically., SPRequestGuid=b4c82c9e-90a7-4000-7c44
-3c52af78ea1f, request-id=b4c82c9e-90a7-4000-7c44-3c52af78ea1f, MS-CV=nizItKeQAEB8RDxSr3jqHw.0, Strict-Transport-Securi
ty=max-age=31536000, X-FRAME-OPTIONS=SAMEORIGIN, SPRequestDuration=102, SPIisLatency=1, MicrosoftSharePointTeamServices
=16.0.0.7108, X-Content-Type-Options=nosniff, X-MS-InvokeApp=1; RequireReadOnly, X-MSEdge-Ref=Ref A: 36059A7BC84248D8BB
44EB130477745C Ref B: AMS04EDGE0606 Ref C: 2017-11-14T11:51:12Z, Content-Length=0, Content-Type=text/plain; charset=utf
-8, Date=Tue, 14 Nov 2017 11:51:12 GMT, P3P=CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo C
NT COM INT NAV ONL PHY PRE PUR UNI", X-Powered-By=ASP.NET'."
At BulkEnqueueOneDriveSite.ps1:73 char:1
+ $loader.Context.ExecuteQuery()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : NotSupportedException

Script Completed

Now this error is somewhat fuzzy and clear at the same time, if you know what to look for.

Login to Sharepoint Online PowerShell:
Connect-SPOService -Url https://tenant-admin.sharepoint.com
Check this setting:
Get-SPOTenant | select legacy*            
            
LegacyAuthProtocolsEnabled            
__________________________            
                     False
Then set the legacy authentication protocol back to enabled:
Set-SPOTenant -LegacyAuthProtocolsEnabled $true
And check once more:
Get-SPOTenant | select legacy*            
            
LegacyAuthProtocolsEnabled            
__________________________            
                      True

This will allow you to login with an account that has disabled the ability for non-modern (legacy) authentication protocols also known as MFA.
Changes may take 1 minute up to 24 hours to take affect.
And when provisioning has taken place don't forget to set it back to "False".

30 October 2017

PowerShell One liners (continuous work in progress)

If you know a nice one liner that should be on here drop me a line.

Enable Remote Desktop locally:
Set-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name fDenyTSConnections -Value 1
Or including the firewall rule:
(Get-WmiObject Win32_TerminalServiceSetting -Namespace root\cimv2\TerminalServices).SetAllowTsConnections(1,1) | Out-Null
(Get-WmiObject -Class "Win32_TSGeneralSetting" -Namespace root\cimv2\TerminalServices -Filter "TerminalName='RDP-tcp'").SetUserAuthenticationRequired(0) | Out-Null
Get-NetFirewallRule -DisplayName "Remote Desktop*" | Set-NetFirewallRule -enabled true
Add a user to blocked senders
Set-MailboxJunkEmailConfiguration -Identity "UserName" –BlockedSendersandDomains @{Add="somebody@domain.com"}
Check if set correctly
Get-MailboxJunkEmailConfiguration -Identity "UserName" | FL BlockedSendersandDomains
To Remove a user from blocked senders
Set-MailboxJunkEmailConfiguration -Identity "UserName" –BlockedSendersandDomains @{Remove="somebody@domain.com"}
Delete the file "desktop.ini" from 2 directories deep:
get-childitem -path \\domain.lan\sharename\users\home\*\* -force -filter "desktop.ini" | foreach ($_) {remove-item $_.fullname -force -verbose 4>> c:\temp\desktopiniresults.txt}
Set UPN to match Mail Address for Office365 use:
Get-User -OrganizationalUnit "domain.com/OUName" -ResultSize unlimited | Where { -Not [string]::IsNullOrEmpty($_.WindowsEmailAddress) } | ForEach { Set-User -Identity $_.Guid.ToString() -UserPrincipalName $_.WindowsEmailAddress.ToString() }
Allow Windows 10 PC in workgroup to manage Hyper-v server:
winrm quickconfig -force
winrm set winrm/config/client ‘@{TrustedHosts=”Name of the Server”}’
Enable protocol logging for IMAP
Set-ImapSettings -Server "CAS01" -ProtocolLogEnabled $true
Disable protocol logging for IMAP
Set-ImapSettings -Server "CAS01" -ProtocolLogEnabled $false
Recreate the Sharedwebconfig.config files for Exchange 2013:
cd %ExchangeInstallPath%\bin
DependentAssemblyGenerator.exe -exchangePath "%ExchangeInstallPath%bin" -exchangePath "%ExchangeInstallPath%ClientAccess" -configFile "%ExchangeInstallPath%ClientAccess\SharedWebConfig.config"
DependentAssemblyGenerator.exe -exchangePath "%ExchangeInstallPath%bin" -exchangePath "%ExchangeInstallPath%FrontEnd\HttpProxy" -configFile "%ExchangeInstallPath%FrontEnd\HttpProxy\SharedWebConfig.config"
Get the list of network profiles on the system.
Get-NetConnectionProfile
Change the network interface to private, use the network interface index number from the previous command.
Set-NetConnectionProfile -InterfaceIndex 10 -NetworkCategory Private
Get Exchange build number:
Get-ExchangeServer | Format-List Name, Edition, AdminDisplayVersion
Get Exchange Schema version:
"Exchange Schema Version = " + ([ADSI]("LDAP://CN=ms-Exch-Schema-Version-Pt," + ([ADSI]"LDAP://RootDSE").schemaNamingContext)).rangeUpper
Set Default Addressbook Policy and Retention Policy for all mailboxes at once:
Get-Mailbox -ResultSize unlimited | Set-mailbox -AddressBookPolicy "Your AddressBookPolicy" -RetentionPolicy "Your - Default Policy"
Quickly add the Exchange PowerShell module to a regular PowerShell console:
Add-PSSnapin *exchange*
Add multiple aliasses at once:
Set-Mailbox "UserName" -EmailAddresses @{add="UserName01@domain.com","UserName02@domain.com","UserName03@domain.com","UserName04@domain.com",
"UserName05@domain.com","UserName06@domain.com","UserName07@domain.com","UserName08@domain.com","UserName09@domain.com","UserName10@domain.com",
"UserName11@domain.com","UserName12@domain.com","UserName13@domain.com","UserName14@domain.com","UserName15@domain.com","UserName16@domain.com",
"UserName17@domain.com","UserName18@domain.com","UserName19@domain.com","UserName20@domain.com"}
List all mailboxes that have a forwarding address
Get-mailbox -Resultsize Unlimited | select DisplayName,ForwardingAddress | where {$_.ForwardingAddress -ne $Null}
Send Output to Clipboard with PowerShell
Get-EventLog application -Newest 1 | clip
Find specific Help articles with Powershell
Get-Help about_
press tab to cycle through the matches
Find white space (Available new mailbox space) in all databases
Get-MailboxDatabase -Status | sort name | select name,@{Name='DB Size (Gb)';
Expression={$_.DatabaseSize.ToGb()}},@{Name='Available New Mbx Space Gb)';Expression={$_.AvailableNewMailboxSpace.ToGb()}}
Create Powershell profile
New-Item -path $profile -type file –force
Edit the newly created profile in the following location
C:\Users\Username\Documents\WindowsPowerShell
Load all Powershell available modules at once:
Get-Module -ListAvailable | Import-Module
Turn off shutdown tracker for Windows server
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Reliability"
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Reliability" -Name ShutdownReasonOn -Value 0
Combine multiple files into one;
Get-ChildItem -filter "c:\temp\*.html" | % { Get-Content $_ -ReadCount 0 | Add-Content "c:\temp\combined_files.html" }
Or:
Get-Content -path c:\temp\eventlogs\*.html | Add-Content -Path C:\temp\Eventlogs\combined.html
Get users with imap enabled:
Get-CASMailbox -ResultSize unlimited | Where-Object {$_.imapenabled -eq "true"} | fl name,imapenabled
Get empty AD groups and email the output;
$body=Get-ADGroup -Filter * -Properties Members | where {-not $_.members} | select Name
Send-MailMessage -smtpserver smtp.domain.lan -subject
 "Empty groups" -to "user1@domain.com,user2@domain.com" -from "user@domain.com" -Body ( $Body | out-string )
Set send on behalf of rights;
Set-Mailbox UserMailbox -GrantSendOnBehalfTo UserWhoSends
View who has which permissions on a user mailbox;

Get-MailboxFolderPermission -Identity "alias:\postvak in" | fl 
(for Dutch)

Get-MailboxFolderPermission -Identity "alias:\inbox" | fl 
(for English)

View who has which permissions on a user calendar;

Get-MailboxFolderPermission -Identity alias:\agenda | fl 
(for Dutch)
Get-MailboxFolderPermission -Identity alias:\calendar | fl 
(for English)

Remove user rights on a mailbox/folder for an other user:
Remove-MailboxFolderPermission -Identity username1:\agenda -User username2
Add user rights on a mailbox/folder for an other user:
Add-MailboxFolderPermission -Identity username1:\agenda -AccessRights Publishingeditor -User username2
MAPI encryption enabled or disabled; (for Outlook 2003 clients)

Get-RpcClientAccess | fl encryp*,server
View blocked ActiveSync devices, in "Blocked" state for longer than a month;

Get-ActiveSync Device | Where {$_.DeviceAccessState -eq "blocked"} | Select DeviceModel | ft -auto
Delete "Blocked" activesync devices, in "Blocked" state for longer than a month;

Get-ActiveSync Device | Where {$_.DeviceAccessState -eq "Quarantined" -and $_.FirstSyncTime
 -lt (Get-Date).AddMonths(-1)} | Remove-ActiveSyncDevice

Delete all ActiveSync devices with DeviceAccessState "Blocked";

Get-ActiveSyncDevice | Where {$_.DeviceAccessState -eq "Blocked"} | 
Remove-ActiveSyncDevice

To retrieve all Exchange-related events:


Get-EventLog Application | Where { $_.Source -Ilike “*Exchange*” } 

12 October 2017

Enable MFA for Exchange Online and Outlook, Skype Online and the Skype client

For the Office 365 services, the default state of modern authentication is:

  • Exchange Online - off by default
  • Skype Online - off by default 
  • SharePoint Online - on by default
This means you have to enable it for Exchange Online and Skype Online after enabling MFA for your users.
Here how:

For Exchange Online:

Connect to Exchange Online PowerShell as shown here.
Do one of these steps:
  1. Run this command to enable modern authentication in Exchange Online:
    Set-OrganizationConfig -OAuth2ClientProfileEnabled $true
  2. Run this command to disable modern authentication in Exchange Online:
    Set-OrganizationConfig -OAuth2ClientProfileEnabled $false
  3. To verify that the change was successful, run this command:
    Get-OrganizationConfig | Format-Table -Auto Name,OAuth*

For Skype Online:


Connect to Skype for Business Online using remote PowerShell: https://aka.ms/SkypePowerShell
Run the following command:
  1. Run this command to enable modern authentication in Skype Online:
    Set-CsOAuthConfiguration -ClientAdalAuthOverride Allowed
  2. Verify that the change was successful by running the following:
    get-CsOAuthConfiguration | select ClientAdalAuthOverride
The output for both will look like this:

Get-OrganizationConfig | Select OAuth2ClientProfileEnabled

OAuth2ClientProfileEnabled
--------------------------
                     False

Set-OrganizationConfig -OAuth2ClientProfileEnabled $True


Get-OrganizationConfig | Select OAuth2ClientProfileEnabled

OAuth2ClientProfileEnabled
--------------------------
                      True

Get-CsOAuthConfiguration | Select ClientAdalAuthOverride

ClientAdalAuthOverride
----------------------
Disallowed

Set-CsOAuthConfiguration -ClientAdalAuthOverride Allowed
Get-CsOAuthConfiguration | Select ClientAdalAuthOverride

ClientAdalAuthOverride
----------------------
Allowed

19 September 2017

Exchange 2013 installing a CU, Schema update required or not?

Update 03-10-2017 - Technet article quote added

From Technet:
Active Directory schema changes in Exchange 2013 cumulative updates CU8 and later

No changes have been made to the Active Directory schema in Exchange 2013 from CU8 onwards. The last cumulative update to include schema changes is currently Exchange 2013 CU7.https://technet.microsoft.com/en-us/library/bb738144(v=exchg.150).aspx


This is some of those things you need to check before updating an Exchange environment every time a new CU gets put out.

Do i need to do a Schema update or not?

I came across this post from Rhoderick Milne,

Table Of Exchange 2013 Schema Versions
Exchange Version
msExchProductId
rangeUpper
MESO objectVersion
Organisation objectVersion
Exchange 2013 RTM
15.00.0516.032
15137
13236
15449
Exchange 2013 CU1
15.00.0620.029
15254
13236
15614
Exchange 2013 CU2
15.00.0712.024
15281
13236
15688
Exchange 2013 CU3
15.00.0775.038
15283
13236
15763
Exchange 2013 SP1
15.00.0847.032
15292
13236
15844
Exchange 2013 CU5
15.00.0913.022
15300
13236
15870
Exchange 2013 CU6
15.00.0995.029
15303
13236
15965
Exchange 2013 CU7
15.00.1044.025
15312
13236
15965
Exchange 2013 CU8
15.00.1076.009
15312
13236
15965
Exchange 2013 CU9
15.00.1104.005
15312
13236
15965
Exchange 2013 CU10
15.00.1130.007
15312
13236
16130
Exchange 2013 CU11
15.00.1156.006
15312
13236
16130
Exchange 2013 CU12
15.00.1178.004
15312
13236
16130
Exchange 2013 CU13
15.00.1210.003
15312
13236
16130
Exchange 2013 CU14
15.00.1236.003
15312
13236
16130
Exchange 2013 CU15
15.00.1263.005
15312
13236
16130
Exchange 2013 CU16+.NET4.6.2
15.00.1293.002
15312
13236
16130
Exchange 2013 CU17
15.00.1320.004
15312
13236
16130
Exchange 2013 CU18
15.00. 1347.002
15312
13236
16130

TechNet documents the expected values for the various Exchange 2013 objects in AD.

Check back here when a new CU is released.

Another top tip from Rhoderick is to install .net 4.6.1 after installing the CU and having the machine rebooted.
At the moment of writing .NET 4.7 is not supported for Exchange 2013 and Exchange 2016 no matter what CU you're on.