Tag Archives: powershell

Active Directory Microsoft Exchange Server Windows Server

Grep, Search, Loops and Basename for Powershell Hotness

Simple request: Search for all files in a directory and the child directories for a specific pattern and then return the filename without the path to the file. There are a few commandlets we end up needing to use:

  • Get-ChildItem: Creates a recursive array of filenames and pipes that output into the For loop.
  • ForEach-Object: Starts a for loop, looping through the output of the command that has been piped into the loop (much easier than an IFS array IMHO).
  • If: This starts the if pattern that ends after the select-string in the below command, but only dumps the $_.PSPath if the pattern is true.
  • Select-String: Searches for the content in the file.
  • Split-Path: This is the Powershell equivalent of basename and dirname. You can use this commandlet to extract parts of the path to a file. In this case, we’ll use the -Leaf option which effectively runs the basename, or just the file name in the path to a file.

Get-ChildItem -include * -recurse | ForEach-Object { if( ( $(Get-Content $_) | select-string -pattern "Finished processing mailbox") ) { $_.PSPath }} | Split-Path -Leaf

You can also search for the files that specifically don’t have that given pattern included in them instead by adding a ! in front of the Get-Content:

Get-ChildItem -include * -recurse | ForEach-Object { if( !( $(Get-Content $_) | select-string -pattern "Finished processing mailbox") ) { $_.PSPath }} | Split-Path -Leaf

Note: This runs recursively from the existing working directory (and yes, you can use pwd to return a path, just like the bash built-in).

Finally, the > operator can then be placed into the end to dump our data to a file:

Get-ChildItem -include * -recurse | ForEach-Object { if( !( $(Get-Content $_) | select-string -pattern "Finished processing mailbox") ) { $_.PSPath }} | Split-Path -Leaf > Complete.txt

 

Active Directory Windows Server

Hey Active Directory, Can I Trade Some PowerShell For A Phone List?

According to how you’ve been creating accounts, you might be the best friend of the office manager, who calls looking to see if you can generate a quick phone list. Or you might be useless. Either way, you should know how to obtain the data and therefore possibly how to be helpful to others. Or again, you might be a lost cause. Sorry, had to be said before I take over the entire Tri-State area. Anyway, let’s assume that you want to just grab the office phone number and that you’ve entered that into Active Directory. So let’s pull that and print it to the screen:

Get-AdUser -Filter * -Properties OfficePhone | FT OfficePhone,UserPrincipalName

Now that you can dump a list to the screen, let’s pipe the output to CSV instead, so we can open it in Excel:

Get-AdUser -Filter * -Properties OfficePhone | FT OfficePhone,UserPrincipalName | grep Export-CSV c:\phonelist.csv

Active Directory Mass Deployment Windows Server Windows XP

Change Active Directory Forest Mode With A Script

Changing the Forest Mode in Active Directory can be scripted. I find this useful when regression testing such tasks in a sandbox (e.g. restore image, automate login, change mode, run tests, etc). The script is very simple. First, you’ll import he ActiveDirectory modules:

Import-Module -Name ActiveDirectory

Then you’ll check for the mode prior to running:

Get-ADForest | Format-Table ForestMode

Then you’ll change the forest and domain modes (one per line):

Set-ADForestMode –Identity “krypted.com” –ForestMode Windows2008Forest
Set-ADDomainMode –Identity “krypted.com” –DomainMode Windows2008Domain

Then you’ll report the result:

Get-ADForest | Format-Table Name , ForestMode

The end result could be as simple as three lines if just testing:

Import-Module -Name ActiveDirectory
Set-ADForestMode –Identity “krypted.com” –ForestMode Windows2008Forest
Set-ADDomainMode –Identity “krypted.com” –DomainMode Windows2008Domain

Windows Server

Setting PowerShell Execution Policies

Microsoft doesn’t want any old tool to execute PowerShell scripts. But sometimes when we’re running a tool, we need the tool to be run in a way that violates the default execution policy. In order to facilitate this, Microsoft has also provided four levels of security for the PowerShell execution policy. These include:

  • Restricted: The default execution policy, which forces commands to be entered interactively.
  • All Signed: Only signed scripts can be run by a trusted publisher.
  • Remote Signed: Any scripts created locally can run.
  • Unrestricted: Any script can run.

To configure an execution policy interactively, simply use the Set-ExecutionPolicy command followed by the name of the execution policy you wish to use. So to run the policy as unrestricted (e.g. while you’re in the midst of a deployment), you could run the following:

Set-ExecutionPolicy Unrestricted

Once run, use the Get-ExecutionPolicy with no options to see that the execution policy is configured as desired:

Get-ExecutionPolicy

Active Directory Windows Server

Import And Export Active Directory Objects In Server 2012

The LDIFDE utility exports and imports objects from and to Active Directory using the ldif format, which is kinda’ like csv when it gets really drunk and can’t stay on one line. Luckily, ldif can’t drive. Actually, each attribute/field is on a line (which allows for arrays) and an empty line starts the next record. Which can make for a pretty messy looking file the first time you look at one. The csvde command can be used to export data into the csv format instead. In it’s simplest form the ldifde command can be used to export AD objects just using a -f option to specify the location (the working directory that we’re running the ldifde command from if using powershell to do so or remove .\ if using a standard command prompt):

ldifde -f .\ADExport.ldf

This exports all attributes of all objects, which overlap with many in a target Active Directory and so can’t be imported. Therefore, you have to limit the scope of what you’re exporting, which you can do in a few ways. The first is to only export a given OU. To limit, you’ll define a dn with a -d flag followed by the actual dn of the OU you’re exporting and then you’d add a -p for subtree. In the following example we’ll export all of the objects from the sales OU to the SalesOUExport.ldf file:

ldifde -d "OU=sales,DC=krypted,DC=local" -p subtree -f .\SalesOUExport.ldf

Restoring objects still results in an error that the server is “Unwilling To Perform” the import because “The modification was not permitted for security reasons.” Basically, this just means “hey I’m not going to import into some of the fields that I know I have to reserve for objects managed by the system, such as creation date (whencreated), last changed date (whenchanged), etc. So we can take some of these and omit them from our export. You can use ADMT or just look at an ldif or csv file to determine which attributes from the schema that you think need to be omitted, but at a minimum it should include objectguid, uSNCreated, uSNChanged, whencreated and when changed (and a lot of the Exchange attributes if you’ve extended the schema for your forest). To omit use the -o and enclose the omitted attributes in parenthesis. In the following example, we’ll export to the SalesOUExportO.ldf file, and add the -o flag to the previous command:

ldifde -d "OU=sales,DC=krypted,DC=local" -p subtree -o "objectguid,uSNCreated,uSNChanged,whencreated,whenchanged" -f .\SalesOUExportO.ldf

You can also omit using the -m flag, which includes only the essential attributes, so we’ll add that to the command as well:

ldifde -d "OU=sales,DC=krypted,DC=local" -p subtree -o "objectguid,uSNCreated,uSNChanged,whencreated,whenchanged" -m -f .\SalesOUExportO.ldf

Use the -l option to limit the attributes being exported to only those specified.

The -r option restricts the export to a given category or class. For example, if we only wanted to export users, we can restrict to objectClass-User

ldifde -d "OU=sales,DC=krypted,DC=local" -p subtree -r "(objectClass=user)" -o "objectguid,uSNCreated,uSNChanged,whencreated,whenchanged" -m -f .\SalesOUExportOM.ldf

Now I’m feeling like we have a good restricted set of data that we’re moving. Let’s go ahead and give importing a shot on a target server. To do so, we’ll just use -i to specify this is an import, followed by -k to say “don’t stop if you have a problem with just one record”, -f to define a file and -j to write a log. We’ll use the working directory for the file path and the log path, assuming this is being done by calling the .exe from within powershell:

ldifde -i -k -f .\SalesOUExportOM.ldf -j .\

Once complete, the exported objects should appear once you close and re-open Active Directory Users and Computers. You can also export one object, then programmatically create objects in an ldif file as needed by importing them into Active Directoryusing ldifde.

Windows Server

Resize Hyper-V .vhdx To Minimum Size

A really neat new feature in 2012R2 is that Hyper-V can resize a running virtual machine (.vhdx) to the smallest possible size, while the virtual machine is running. To do so, use Get-VM in PowerShell. Here, we’ll use the -Path option to define the location of our vhdx, the -ToMinimumSize option to indicate that we’d like to shrink it down as low as we can go and -AsJob so it runs in the background:

Resize-VHD –Path D:\myVM.vhdx –ToMinimumSize -AsJob

Microsoft Exchange Server Network Infrastructure Windows Server

Delete Messages From Exchange Using PowerShell

Before I type anything else, allow me to state that running a search and deleting things with a script from a users (or a loop of all users) is a very dangerous process. However, I’ve often noticed that an outbreak of bad things can cause us to do some pretty awesome things. So, you can use the get-Mailbox cmdlet to pipe a mailbox into the search-mailbox cmdlet and from there use the -SearchQuery option to search for an attachment, following the attachment option with a filename and then delete it using the -DeleteContent option. The example would be as follows:

Get-Mailbox -Identity “cedge” | Search-Mailbox -SearchQuery attachment:ichatsmileys.pkg.zip -DeleteContent

You can also filter search queries based on To, From, CC, Subject, Sent date and of course, policy data. You can also use the -TargetMailbox and -TargetFolder options to move messages into a quarantine mailbox/space.

Microsoft Exchange Server

Configure Exchange Mailbox Database Maintenance Schedules

Exchange databases need maintenance. This maintenance defragments the databases, reindexes the databases and performs other tasks necessary for long-term sustainability of the databases.

To configure maintenance, open the Exchange Management Console and then under Organization Configuration select Mailbox.

Screen Shot 2013-10-10 at 2.41.37 PM
At the Database Management tab, double-click on the database to schedule maintenance for and click on the Maintenance tab. Here, check the box for Enable background maintenance and then select one of the schedules for which Exchange maintenance occurs. This schedules a nightly database maintenance window where Exchange Server can perform the necessary operations on a given database.

Screen Shot 2013-10-10 at 2.41.29 PM

Alternatively, if you have a lot of databases or need to batch change these things, or just want to do so through PowerShell ’cause you’re that frickin’ awesome, use the Set-MailboxDatabase cmdlet in PowerShell. To do so, open PowerShell from within Exchange and then run the Set-MailboxDatabase cmdlet along with -identity followed by the quoted name of the server\name of the database and then use the -MaintenanceSchedule option to identify the schedule (which should also be quoted), as follows:

Set-MailboxDatabase -Identity "Exchange\MailboxDatabase" -MaintenanceSchedule "Sun.2:00-Sun.6:00"

Alternatively there are two other ways to get an Exchange database defragmented. The first is to manually defrag the database using a tool called eseutil. In this case, you’ll encounter from 5 to 20 minutes of downtime per gig of the Information Store. To do so, run esetuil. You can run the tool, specifying that you are defragmenting a /d for database and /ds for the directory. You will need enough space on the drive with the edb files on it to make a copy of the database (double-click on an Information Store to see the path). In this example we’ll specify a temporary directory to use for defraging on another volume, as follows:

eseutil /d /ds /tc:D:\backup\eseutildefrag.edb /p

Note: To use a temporary volume increases the amount of time per gig to defrag the database.

In todays email archival and retention cycles databases are growing to ridiculous numbers though. Therefore, offline defragmentation is often no longer an option. So the second option for manual defragmentation is to actually spin up another database, perform a Local Move Request of all users to the new database and then delete your original production database. Doing so allows you to move users without impacting their ability to work, get the size of the total Information Store(s) down and also get a squeaky clean database in the process.

Active Directory Windows Server

Rename a Windows 2012 Server Using PowerShell

When you are creating a bunch of Server 2012 Virtual Machines (or physical machines for that matter) it is helpful to programmatically change their names. To do so, use the Rename-Computer PowerShell cmdlet followed by the name you want the computer to have, as follows (assuming a name of 2012.krypted.com):

Rename-Computer 2012.krypted.com

Before you do anything else (e.g. bind to AD) you should then reboot the host, using the Restart-Computer cmdlet:

Restart-Computer