MVP - Most Valuable Professional
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 Server, Microsoft 365, Microsoft Teams, and Cloud Security.

Being in a situation where you need to recover IT components or even a whole IT infrastructure after a disastrous event can be stressful. It would help if you stayed concentrated while dealing with the constant status requests by the management.

In such a situation, it can help to isolate your mind by listening to music. Music that helps you focus your thoughts, anger, and feelings in such a moment.

Maybe you find my Spotify playlist helpful. The playlist contains about 12 hours of music.

Listening to music using a headphone is good, but playing music loud and feeling the rhythm and every single bass is much better.

Enjoy.

 

 

Read More »

PowerShellYou sometimes need some (or even many) test user objects in Active Directory.

This script helps you create any number of test users in your Active Directory domain, which you can easily enable for on-premises or remote mailboxes afterward.

 

The Script

# Number of user accounts to create
$UserCount = 5
$RandomPassword = $true
$DefaultPassword = 'Pa55w.rd'

# User name prefix
# New user object will be named TestUser1, TestUser2, ...
$TestUserPrefix = 'TestUser'

# User object properties
$GivenName = 'Test'
$Surname = 'User'
$Company = 'Varunagroup'
$JobTitle = @('Junior Consultant','Senior Consultant','Technical Consultant','Business Consultant')
$PreferredLanguage = 'de-DE'

# Name of the new organizational unit for test user object
$TestOU = 'Test User'

# Target OU path where the script creates the new OU 
$TargetOU = 'OU=IT,dc=varunagroup,dc=de'

# Import Active Directory PowerShell Module
Import-Module -Name ActiveDirectory 

# Build OU Path
$UserOUPath = ("OU={0},{1}" -f $TestOU, $TargetOU)

# Check if OU exists
$OUExists = $false

try {
   $OUExists = [adsi]::Exists("LDAP://$UserOUPath")
}
catch {
   $OUExists =$true   
}

if(-not $OUExists) { 
   # Create new organizational unit for test users
   New-ADOrganizationalUnit -Name $TestOU -Path $TargetOU -ProtectedFromAccidentalDeletion:$false -Confirm:$false
}
else {
   Write-Warning ('OU {0} exists please delete the OU and user objects manually, before running this script.' -f $UserOUPath)
   Exit
}

Write-Output ("Creating {0} user object in {1}" -f $UserCount, $UserOUPath)

# Create new user objects
1..$UserCount | ForEach-Object {

   # Get a random number for selecting a job title
   $random = Get-Random -Minimum 0 -Maximum (($JobTitle | Measure-Object). Count - 1)

   # Set user password
   if($RandomPassword) {
      # Create a random password
      $UserPassword = ConvertTo-SecureString -String (-join ((33..93) + (97..125) | Get-Random -Count 25 | % {[char]$_})) -AsPlainText -Force
   }
   else {
      # Use a fixed password
      $UserPassword = ConvertTo-SecureString -String $DefaultPassword -AsPlainText -Force
   }

   # Create a new user object
   # Adjust user name template and other attributes as needed
   New-ADUser -Name ("{0}{1}" -f $TestUserPrefix, $_) `
   -DisplayName ("{0} {1}" -f $TestUserPrefix, $_) `
   -GivenName $GivenName `
   -Surname ("$Surname{0}" -f $_) `
   -OtherAttributes @{title=$JobTitle[$random];company=$Company;preferredLanguage=$PreferredLanguage} `
   -Path $UserOUPath `
   -AccountPassword $UserPassword `
   -Enabled:$True `
   -Confirm:$false
}

 

Enable mailboxes

Use your on-premises Exchange Management Shell to enable all test users with an on-premises mailbox.

$UserOU = 'OU=Test User,OU=IT,dc=varunagroup,dc=de'
Get-User -OrganizationalUnit $UserOU | Enable-Mailbox -Confirm:$false

 

Use your on-premises Exchange Management Shell to enable all test users with a new remote mailbox in Exchange Online. Do not forget to change the tenant name of the remote routing address.

Get-User -OrganizationalUnit 'OU=Test User,OU=IT,dc=varunagroup,dc=de' | %{Enable-RemoteMailbox
 -Identity $_ -Confirm:$false -RemoteRoutingAddress "$($_.SamAccountName)@TENANT.mail.onmicrosoft.com"}

 

You find the most recent version of the script at GitHub.

 

Links

 

Enjoy.

 

Read More »

Sometimes you might be interested in gathering a list of all computer from an Active Directory domain in preparation for migration.

You can gather a list of all computer objects using the following command.

# Fetch a sorted list of all computer objects
Get-ADComputer -Filter * -Property * | Sort-Object Name 

 

The wildcard used with the Property parameter fetches all available attributes for a computer object. Check the available attributes in the result set to identify the attributes you are interested in.

# Example output for the first computer object gathered from Active Directory
(Get-ADComputer -Filter * -Property * | Sort-Object Name)[0]

AccountExpirationDate                : 
accountExpires                       : 9223372036854775807
AccountLockoutTime                   : 
AccountNotDelegated                  : False
AllowReversiblePasswordEncryption    : False
BadLogonCount                        : 0
badPasswordTime                      : 0
badPwdCount                          : 0
CannotChangePassword                 : False
CanonicalName                        : DOMAIN.local/Computers/COMPUTER01
Certificates                         : {}
CN                                   : COMPUTER01
codePage                             : 0
CompoundIdentitySupported            : {False}
countryCode                          : 0
Created                              : 9/2/2013 3:01:13 PM
createTimeStamp                      : 9/2/2013 3:01:13 PM
Deleted                              : 
Description                          : 
DisplayName                          : 
DistinguishedName                    : CN=COMPUTER01,CN=Computers,DC=DOMAIN,DC=local
DNSHostName                          : COMPUTER01.DOMAIN.local
DoesNotRequirePreAuth                : False
dSCorePropagationData                : {12/31/1600 7:00:00 PM}
Enabled                              : True
HomedirRequired                      : False
HomePage                             : 
instanceType                         : 4
IPv4Address                          : 
IPv6Address                          : 
isCriticalSystemObject               : False
isDeleted                            : 
KerberosEncryptionType               : {RC4, AES128, AES256}
LastBadPasswordAttempt               : 
LastKnownParent                      : 
lastLogoff                           : 0
lastLogon                            : 130942520427754509
LastLogonDate                        : 12/10/2015 3:02:53 PM
lastLogonTimestamp                   : 130942513734007331
localPolicyFlags                     : 0
Location                             : 
LockedOut                            : False
logonCount                           : 194
ManagedBy                            : 
MemberOf                             : {}
MNSLogonAccount                      : False
Modified                             : 12/10/2015 3:02:53 PM
modifyTimeStamp                      : 12/10/2015 3:02:53 PM
msDS-SupportedEncryptionTypes        : 28
msDS-User-Account-Control-Computed   : 0
Name                                 : COMPUTER01
nTSecurityDescriptor                 : System.DirectoryServices.ActiveDirectorySecurity
ObjectCategory                       : CN=Computer,CN=Schema,CN=Configuration,DC=DOMAIN,DC=local
ObjectClass                          : computer
ObjectGUID                           : da59afcc-e00a-430b-9cbc-01adeed568f3
objectSid                            : S-1-5-21-3143343262-845931634-422089675-1179
OperatingSystem                      : Windows 7 Professional
OperatingSystemHotfix                : 
OperatingSystemServicePack           : Service Pack 1
OperatingSystemVersion               : 6.1 (7601)
PasswordExpired                      : False
PasswordLastSet                      : 12/2/2014 7:21:09 AM
PasswordNeverExpires                 : False
PasswordNotRequired                  : False
PrimaryGroup                         : CN=Domain Computers,CN=Users,DC=DOMAIN,DC=local
primaryGroupID                       : 515
PrincipalsAllowedToDelegateToAccount : {}
ProtectedFromAccidentalDeletion      : False
pwdLastSet                           : 130619964697110685
SamAccountName                       : COMPUTER01$
sAMAccountType                       : 805306369
sDRightsEffective                    : 15
ServiceAccount                       : {}
servicePrincipalName                 : {RestrictedKrbHost/COMPUTER01, HOST/COMPUTER01, 
                                       RestrictedKrbHost/COMPUTER01.DOMAIN.local, HOST/COMPUTER01.DOMAIN.local}
ServicePrincipalNames                : {RestrictedKrbHost/COMPUTER01, HOST/COMPUTER01, 
                                       RestrictedKrbHost/COMPUTER01.DOMAIN.local, HOST/COMPUTER01.DOMAIN.local}
SID                                  : S-1-5-21-3143343262-845931634-422089675-1179
SIDHistory                           : {}
TrustedForDelegation                 : False
TrustedToAuthForDelegation           : False
UseDESKeyOnly                        : False
userAccountControl                   : 4096
userCertificate                      : {}
UserPrincipalName                    : 
uSNChanged                           : 1721509
uSNCreated                           : 45981
whenChanged                          : 12/10/2015 3:02:53 PM
whenCreated                          : 9/2/2013 3:01:13 PM

 

As a next step, you gather the selected information and 

# Fetch data for an operating system overview, sorted by property Name only
Get-ADComputer -Filter * -Property * | Sort-Object Name | Select Name,OperatingSystem,OperatingSystemServicePack,OperatingSystemVersion 

# Fetch data for an operating system overview, sorted by property OperatingSystem first, then Name 
Get-ADComputer -Filter * -Property * | Sort-Object OperatingSystem,Name | Select Name,OperatingSystem,OperatingSystemServicePack,OperatingSystemVersion 

 

You can export the gathered information to a comma separated file easily using the Export-Csv cmdlet.

# Export the gathered and sorted information to a CSV file using a semicolon as the delimiter
# Adjust the file path for the CSV file to fit your environment
Get-ADComputer -Filter * -Property * | Sort-Object OperatingSystem,Name | Select Name,OperatingSystem,OperatingSystemServicePack,OperatingSystemVersion | Export-Csv -Path C:\SCRIPTS\ComputerOverview.csv -NoClobber -NoTypeInformation -Delimiter ';' 

 

Link

 

Enjoy!

Read More »
On December 20, 2017
0 Comment
4442 Views

Issue

Recently I was facing an issue where Windows Server 2012 R2 reported remaining 22% of free disk space of one of the Exchange Server data volumes. The Exchange Server data volumes are connected using mount points. 

Before trying to identify any issues in regards to hidden system files or streams, I checked the volume shadow copy configuration using the Disk Management MMC.

Windows Disk Management showed that volume C: was using a mounted volume as shadow copy target.

Disk Manager Overview and Shadow Copy Details

Examining the available disk space using the Get-Diskspace.ps1 PowerShell script, it showed that WMI was reporting the FreeSpace the same way as the Disk Management.

[PS] D:\SCRIPTS\Get-Diskspace>.\Get-Diskspace.ps1 -ComputerName EX01
Fetching Volume Data from EX01

Name                                              Capacity (GB) FreeSpace (GB) BootVolume SystemVolume FileSystem
----                                              ------------- -------------- ---------- ------------ ----------
E:\ExchangeDatabases\DatabaseSet1\                         2048           1083      False        False NTFS
E:\ExchangeDatabases\DatabaseSet2\                         2048            445      False        False NTFS
E:\ExchangeDatabases\DatabaseSet3\                         2048           1219      False        False NTFS
E:\ExchangeDatabases\DatabaseSet4\                         2048           1091      False        False NTFS

The only viable solution to reclaim the wasted disk space was to remove the shadow copy of volume C.

Solution

First I checked the current list of shadow copies using the vssadmin command line tool.

D:\>vssadmin list shadows
vssadmin 1.1 - Volume Shadow Copy Service administrative command-line tool
(C) Copyright 2001-2013 Microsoft Corp.

Contents of shadow copy set ID: {eb09ce08-f8a6-47ea-b48d-2d6da7591d4e}
   Contained 1 shadow copies at creation time: 23.06.2017 16:05:56
      Shadow Copy ID: {3684b224-bca2-42c4-a0b3-43b7d0db2d96}
         Original Volume: (C:)\\?\Volume{df40ac48-f610-11e3-80ce-806e6f6e6963}\
         Shadow Copy Volume: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1
         Originating Machine: ex01.granikossolutions.eu
         Service Machine: ex01.granikossolutions.eu
         Provider: 'Microsoft Software Shadow Copy provider 1.0'
         Type: ApplicationRollback
         Attributes: Persistent, No auto release, Differential

The vssadmin tool does not clearly state the path to the shadow copy volume. Therefore, it is much more convenient to identify the shadow copy target using Disk Management. But the output shows that the shadow copy is nearly six months old. So it's safe to delete this orphaned shadow copy.

You can easily delete all shadow copies of a selected volume using the following command

vssadmin delete shadows /for=c: /all

But it turned out that the shadow copy could not be deleted, even with administrative credentials in use.

D:\>vssadmin delete shadows /for=c: /all
vssadmin 1.1 - Volume Shadow Copy Service administrative command-line tool
(C) Copyright 2001-2013 Microsoft Corp.

Error: Snapshots were found, but they were outside of your allowed context.  Try removing them with the
backup application which created them.

Needless to say, that a well-known third party solution is in use to backup the servers. The shadow copy remainers are copies created by the backup solution and were not properly removed after backup due to a system failure during backup.

But how can you remove the current shadow copy without tempering the exisiting permissions for your account?

Simply use the Disk Management MMC to modifx the current shadow copy configuration and the shadow copy is removed.

  • Open Disk Management MMC
  • Open Properties windows of an existing volume
  • Select the Shadow Copies tab
  • Select the source volume having the shadow copy configured (see screenshot above)
  • Click the Settings button
    • Leave the Located on this volume setting unchanged
    • Change the Maximum size setting to Use limit 320 MB
    • Click OK

Change Shadow Copy Settings to Remove Orphaned Copy

Switch to the command line and check for existing shadow copies.

D:\>vssadmin list shadows
vssadmin 1.1 - Volume Shadow Copy Service administrative command-line tool
(C) Copyright 2001-2013 Microsoft Corp.

No items found that satisfy the query.


The oprhaned shadow copy is gone.

Now open the Settings windows for the source volume again and change the Located on this volume to be the same as the source volume anfd change the Use Limit to the same value for the volume that is configured on other servers.

Volume Shadow Copy Settings

Enjoy Volume Shadow Copies

 

Links

 

 

Read More »
On May 16, 2017
0 Comment
1727 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 »