de-DEen-GB
 
rss

Just can't get enough of IT

This blog is about mostly anything in IT. But the primary focuses are Microsoft Technologies like Exchange, Office 365, Azure and Cloud Security.
On May 16, 2017
0 Comment
363 Views

Microsoft Certified TrainerMy application as Microsoft Certified Trainer for the next year has been accepted by Microsoft.

My workshops and MOC courses focus on:

  • Exchange Server 2016 / 2013 / 2010
  • Office 365
  • Microsoft Azure
  • Active Directory Federation Services
  • Cloud Security

i am looking forward to a third successful year as MCT.

If you are looking for additonal information about workshops provided by Granikos check this page: https://www.granikos.eu/en/Consulting/Workshops

 

 

 

 

Read More »

When you delete a public folder using a legacy Outlook client, you can easily restore the deleted folder and it's content using the Recover Deleted Items function. 

Due to a fancy trick implemented in Outlook 2013 and Outlook 2016 the recovered folder will not be recovered using it's full name.

This phenomenon has been verified with Exchange On-Premises and Exchange Online on the server side and Outlook 2013/2016 and Outlook 365 ProPlus.

The following example uses public folders in Exchange Online and Outlook 365 ProPlus.

Example

In this example I will delete and recover a public folder named My Public Folder.

Public folder hierarchy before deletion

After deletion of My Public Folder and it's content, I need to select the original parent folder and click the Recover Deleted Items button in the button bar.

Select original parent folder

Recover Deleted Items

The Recover Deleted Items dialogue opens and we select the deleted item for recovery. The dialogue displays the original name of the deleted folder.

Recover Deleted Items (DE)

After recovering the deleted folder the folder is recovered with the first character only.

Recovered public folder with first character only

That's an annoying result in regards to customer self-care when users restore deleted items on their own behalf.

But wait, there is a solution available.

Solution

The solution requires today's primary administrative tool available: PowerShell.

Step 1

Get an overview of public folders currently located in the public folder dumpster

Get-PublicFolder –Identity “\NON_IPM_SUBTREE” –Recurse 

Name             Parent Path
----             -----------
NON_IPM_SUBTREE
[...]
My Public Folder \NON_IPM_SUBTREE\DUMPSTER_ROOT\DUMPSTER_EXTEND\RESERVED_1\RESERVED_1\65722859-3...
Sub Folder 1     \NON_IPM_SUBTREE\DUMPSTER_ROOT\DUMPSTER_EXTEND\RESERVED_1\RESERVED_1\65722859-3...
Sub Folder 2     \NON_IPM_SUBTREE\DUMPSTER_ROOT\DUMPSTER_EXTEND\RESERVED_1\RESERVED_1\65722859-3...
[...]

 

Step 2

Export the list of public folders currently located in the public folder dumpster and find the identity of the deleted public folder you want to recover

Get-PublicFolder –Identity “\NON_IPM_SUBTREE” –Recurse  | fl | Out-File D:\TMP\publicfolderdumpster.txt

publicfolderdumpster.txt excerpt:


RunspaceId                     : 6ce9588e-829b-4592-aedc-85f9a2e2c963
Identity                       : \NON_IPM_SUBTREE\DUMPSTER_ROOT\DUMPSTER_EXTEND\RESERVED_1\RESERVED_1\65722859-366a-4e0
                                 9-81fe-ea576ec7a6f7\My Public Folder
Name                           : My Public Folder
MailEnabled                    : False
MailRecipientGuid              : 
ParentPath                     : \NON_IPM_SUBTREE\DUMPSTER_ROOT\DUMPSTER_EXTEND\RESERVED_1\RESERVED_1\65722859-366a-4e0
                                 9-81fe-ea576ec7a6f7

Step 3

Recover the deleted public folder to the correct parent target folder

Set-PublicFolder –Identity "\NON_IPM_SUBTREE\DUMPSTER_ROOT\DUMPSTER_EXTEND\RESERVED_1\RESERVED_1\65722859-366a-4e09-81fe-ea576ec7a6f7\My Public Folder" –Path “\TestFolders” –Verbose

As a result the public folder is recovered with it's original name.

Notes

There are some other things to consider when recovering deleted modern public folders.

Public folders originally located in the hierarchy root are always recovered to the public folder mailbox holding the primary hierarchy. 

Public folders originally located in the hierarchy root will replace the permissions of child public folders when restored. 

More on these default restore behaviours can be read here.

Links

Nevertheless, enjoy modern public folders.

 

 

Read More »

The PowerShell script to Set mailbox quotas at database or mailbox level the simple way has been updated to Version 1.4.

The code has been refactored to functions and has received some PowerShell hygiene patters.

Please report any issues directly at Github.

If you like the script, please rate the script at TechNet Gallery.

Enjoy!

 

 

Read More »
On April 10, 2017
0 Comment
524 Views

 

Exchange Server 2013 Exchange Server 2016 The PowerShell script to purge Exchange Server and IIS log files has been updated to version 2.0.

Release 2.0 allows for copying of files that will be deleted to be copied to a central file repository. The script will create a folder per server and the full log file folder structure will be preserved.

The next release will contain an option to compress the copied log files.

Added code:

function Copy-LogFiles {
  [CmdletBinding()]
  param(
    [string]$SourceServer,
    [string]$SourcePath,
    $FilesToMove
  )

  if($SourceServer -ne '') { 

    # path per SERVER for zipped archives
    $ServerRepositoryPath = Join-Path -Path $RepositoryRootPath -ChildPath $SourceServer

    # subfolder used as target for copying source folders and files
    $ServerRepositoryLogsPath = Join-Path -Path $ServerRepositoryPath -ChildPath $LogSubfolderName

    $ServerRepositoryPath = Join-Path -Path $RepositoryRootPath -ChildPath $SourceServer

    if(!(Test-Path -Path $ServerRepositoryPath)) {
      # Create new target directory for server, if does not exist
      $null = New-Item -Path $ServerRepositoryPath -ItemType Directory -Force -Confirm:$false
    }

    foreach ($File in $FilesToMove) {
      # target directory
      $targetDir = $File.DirectoryName.Replace($TargetServerFolder, $ServerRepositoryLogsPath)

      # target file path
      $targetFile = $File.FullName.Replace($TargetServerFolder, $ServerRepositoryLogsPath)
      
      # create target directory, if not exists
      if(!(Test-Path -Path $targetDir)) {$null = mkdir -Path $targetDir}

      # copy file to target
      $null = Copy-Item -Path $File.FullName -Destination $targetFile -Recurse -Force -Confirm:$false -ErrorAction SilentlyContinue

    }-Force   
    
    if($ZipArchive) {
      # zip copied log files
      #
      <# NOT FULLY TESTED YET 
      $Archive = Join-Path -Path $ServerRepositoryPath -ChildPath $ArchiveFileName
      $logger.Write(('Zip copied files to {0}' -f $ArchiveFileName))

      if(Test-Path -Path $Archive) {Remove-Item $Archive -Force -Confirm:$false}

      Add-Type -AssemblyName 'System.IO.Compression.FileSystem'
      [IO.Compression.ZipFile]::CreateFromDirectory($ServerRepositoryLogsPath,$Archive)

      #>
    } 
  }  
}

Note

Links

Social

 

 

Read More »

Office 365Problem

You can block an user from logging on to Office 365 by setting the BlockCredential attribute to $true.

Set-MsolUser -UserPrincipalName myuser@mcsmemail.de -BlockCredential $true

But the MSOL user attribute is reverted to $false, when ADD Connect synchonization cycle runs.

This happens, because the local Active Directory attribute accountEnabled is used to controll the BlockCredential attribute in Azure AD.

Solution

If your IT operation requires the ability to have enabled users in your local Active Directory infrastructure and you need to prevent logon to cloud services you need to prevent the accountEnabled attribute from being synchronized to Azure AD. This might not necessarily be a general requirement during normal operations, but might be useful while doing a Proof-of-Concept.

Just exclude the attribute from the Azure Active Directory connector in the Synchronization Service Manager.

Excluding the accountEnabled attribute from being synchronized with Azure AD

The following script disables all users excluding

  • Users following a specific naming pattern
  • Users listed in a string array
# Userfilter
$UserExceptions = ("Sync_SYNC01_add98768492f@mcsmemail.onmicrosoft.com","SPO-SRV-ACCOUNT@mcsmemail.de","SynchedAdmin@mcsmemail.de")

# Fetch synchronized users 
$DomainAccounts = Get-MsolUser -EnabledFilter EnabledOnly -MaxResults 5000 | Where-Object -Property LastDirSyncTime -ne $null

# Select synchronized users not following the pattern ADM*@mcsmemail.de (admin accounts in this case)
$DomainAccountsWithoutAdmins =  $DomainAccounts | Where-Object -Property UserPrincipalName -notlike "ADM*@mcsmemail.de"

# Exclude accounts listed in $UserExceptions
$DomainAccountsWithoutAdminsFiltered = $DomainAccountsWithoutAdmins | Where-Object -Property UserPrincipalName -NotIn $UserExceptions
 

# Now block cloud logon for all filtered users
ForEach ($User2Block in $DomainAccountsWithoutAdminsFiltered) {
  Write-Host ('Disabling User: {0}.UserPrincipalName)' -f $User2Block)
  Set-MsolUser -UserPrincipalName $User2Block.UserPrincipalName -BlockCredential $true
}

Enjoy Office 365.

 

 

 

Read More »