Categories
Office 365 PowerShell

Rotate images in ADFS 3.0

ADFS 3.0 is otherwise known as ADFS 2012 R2 since it is available only on Server 2012 R2. As I gain some experience with it, one of the nice configuration options is the ability to use PowerShell to customize the sign-in page.

Among the customizations we’ve made is one to help keep our sign-in page from looking stale over time. I wrote this simple PowerShell script to rotate the large “illustration” image occasionally. It runs as a Scheduled Task, and pulls approved images randomly from a file system folder. The script also logs which image was in place at any given time in case that happens to be interesting to someone at some point.

cd X:\path\images
$RandomImage = Get-ChildItem | Get-Random | %{((Get-Item $_).VersionInfo).FileName}
(Get-Date -format G) + " $RandomImage" | Out-File X:\path\Logs\IllustrationRandomizer.log -Append
Set-AdfsWebTheme -TargetName Custom_Theme -Illustration @{path=$RandomImage}

Categories
PowerShell

PowerShell error with Get-ADUser user -Properties *

After upgrading some of our servers to Server 2012 R2, we’ve discovered a bug in the PowerShell 4.0 Get-ADUser cmdlet. When running the command Get-ADUser username -Properties *, the cmdlet returns the following error:

Get-ADUser : One or more properties are invalid.
Parameter name: msDS-AssignedAuthNPolicy
At line:1 char:1
+ Get-ADUser username -Properties *
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (username:ADUser) [Get-ADUser], ArgumentException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.ArgumentException,Microsoft.ActiveDirectory.Management.Comm
ands.GetADUser

Mike F Robbins researched the error in the following blog post, and determined that the issue occurs with PowerShell 4.0 run against Server 2008 R2 domain controllers. The issue is that two attributes, AuthenticationPolicy and AuthenticationPolicySilo, exist in a Server 2012 R2 Active Directory but do not exist in a Server 2008 R2 Active Directory. The Server 2012 R2 RSAT tools expect the attributes to exist in both environments, so an error is returned in the Server 2008 R2 Active Directory environment.

http://mikefrobbins.com/2013/11/07/windows-8-1-rsat-powershell-cmdlets-get-aduser-get-adcomputer-one-or-more-properties-are-invalid/

As Mike points out, a good workaround is to use PowerShell implicit remoting to process the commands on the domain controllers themselves. However, in the meantime I’m able to process the command from other downlevel OS machines, which is fine in my case for now.

I’ve submitted the case to Microsoft Premier who has confirmed the bug and escalated to the Platforms Team. I’ll post updates here as I get them.

Categories
PowerShell

SQL Server PowerShell Module (SQLPS)

SQL Server provides a Windows PowerShell module called sqlps that is used to import the SQL Server components into Windows PowerShell. The sqlps module loads two Windows PowerShell modules:

  • A SQL Server provider, which enables a simple navigation mechanism similar to file system paths. You can build paths similar to file system paths, where the drive is associated with a SQL Server management object model, and the nodes are based on the object model classes. You can then use familiar commands such as cd and dir to navigate the paths similar to the way you navigate folders in a command prompt window. You can use other commands, such as ren or del, to perform actions on the nodes in the path.
  • A set of cmdlets, which are commands used in Windows PowerShell scripts to specify a SQL Server action. The SQL Server cmdlets support actions such as running a sqlcmd script containing Transact-SQL or XQuery statements.

More details here: http://msdn.microsoft.com/en-us/library/hh245198.aspx

Although the SQLPS module is installed along with SQL Server, you do not have to install SQL Server to obtain the module. You simply need to install three stand-alone packages from the Microsoft® SQL Server® 2012 Feature Pack, available here:
http://www.microsoft.com/en-us/download/details.aspx?id=29065

Install the following packages in this order:

  1. Microsoft® System CLR Types for Microsoft® SQL Server® 2012 (SQLSysClrTypes.msi)
  2. Microsoft® SQL Server® 2012 Shared Management Objects (SharedManagementObjects.msi)
  3. Microsoft® Windows PowerShell Extensions for Microsoft® SQL Server® 2012 (PowerShellTools.msi)

Be sure to select the appropriate package platform for each, either x86 or x64.

To load the sqlps module in Windows PowerShell:

Import-Module sqlps

(You can include the -DisableNameChecking parameter if you’re concerned about suppressing the Encode-Sqlname and Decode-Sqlname warning.)

Thanks to Max Trinidad for his article explaining this information. http://www.maxtblog.com/2012/09/create-powershell-smo-scripts-without-installing-sql-server/

Categories
PowerShell

ActiveDirectory module and UAC

I have noticed a few odd behaviors with PowerShell’s ActiveDirectory module, one regarding the msDS-UserPasswordExpiryTimeComputed attribute of the Get-ADUser cmdlet, and another regarding the New-ADServiceAccount cmdlet.

On a brand new Server 2008 R2 domain, the following command returns values for only a small percentage of the accounts in the domain but the vast majority of accounts return with no value.

Get-ADUser -filter * -Properties “msDS-UserPasswordExpiryTimeComputed” | ft name, “msDS-UserPasswordExpiryTimeComputed” –AutoSize

Also on this domain, issuing the following command often results in an “Access is denied” error, but not always. In fact, typically if I receive the error and then leave my RDP session to the computer open for 30 to 60 minutes and try command again (hit the Up Arrow key on the keyboard), the command runs without error.

New-ADServiceAccount svc_test

This seems to indicate a general problem with the ActiveDirectory PowerShell module.

The following article pointed me in the right direction for a workaround.
http://social.technet.microsoft.com/Forums/en-US/windowsserver2008r2general/thread/5947c0eb-9549-4161-afa1-edb451fc742f

The problem appears to be a bug in the way the ActiveDirectory module behaves when User Account Control (UAC) is enabled. The workaround is to disable UAC, which requires a reboot. When UAC is left enabled, even when PowerShell is run with elevated permissions, the problem still occurs.

I’ve confirmed the experiences above both on domain controllers and on member servers, and in two different Active Directory forests.

Categories
PowerShell

Look for orphaned Active Directory home directories

This PowerShell script will iterate through all home directory folders in our Windows file share server and search Active Directory for a homeDirectory path value that ends with that folder name (it actually looks for *\<folderName> so it will only return exact matches).

The script has to be run from a location that has network access and read permissions on the physical volume on the file share server, and also requires the Active Directory PowerShell module to be loaded.

$strHomeServer = "\\server"
$strUsersPath =  "\l$\users\"
$arrDirectories = Get-ChildItem $strHomeServer$strUsersPath | where {$_.attributes -match "directory"}
Write-Host "Number of home directories: $arrDirectories.count" | Out-File C:\scripts\homeDirAudit.txt -Append
$arrDirectories | %{
$objDirectory = $_
# \5c is the LDAP escape sequence for the \ character
#
this info from help about_ActiveDirectory_Filter
$searchString = "*\5c" + $_
$objUser = (Get-ADUser -Filter {homeDirectory -like $searchString} -Properties homeDirectory)
if (-not $objUser) { "$objDirectory not found!" }
else { $objUser | select @{n='Folder Name';e={$objDirectory}}, name, homeDirectory }
} | Out-File C:\scripts\homeDirAudit.txt -Append

Categories
PowerShell

Detecting disconnected Exchange mailboxes

Here’s how to detect Active Directory accounts that had an Exchange 2010 SP1 mailbox at one time, but the mailbox has since been disconnected, aka disabled.

Essentially find all accounts where a msExchWhenMailboxCreated value exists and a homeMDB value does not exist.

Get-ADUser -LDAPFilter "(&(msExchWhenMailboxCreated=*)(!homeMDB=*))" -Properties CanonicalName, msExchWhenMailboxCreated | sort CanonicalName | ft CanonicalName, msExchWhenMailboxCreated -AutoSize

– or-

Get-ADUser -Filter {(msExchWhenMailboxCreated -like "*") -and -not (homeMDB -like "*")} -Properties CanonicalName, msExchWhenMailboxCreated | sort CanonicalName | ft CanonicalName, msExchWhenMailboxCreated -AutoSize

This allows us to know before creating a mailbox for a user whether we should first bother to look for a disconnected mailbox that may already exist for the user.