SCCM 2012 Distribution Point Certificate: Cannot access the file that you specified

When trying to import a certificate into a SCCM 2012 distribution point, you may receive an error message: “Cannot access the file that you specified”. This can occur even if you’ve specified a certificate on the local machine, and specified the correct password. It can even happen if you’re trying to change other configuration on a DP.

The reason for this error is that unless the Configuration Manager console is running as administrator, it cannot access the file. To make this work, simply right click the SCCM console and choose Run As Administrator. You will then be able to open it up and configure the certificate as necessary.

Group Policy WMI Queries for Windows 8 do not work for Windows 8.1

With Windows 8.1, Microsoft have increased the operating system’s internal version number from Windows 8’s 6.2.x to 6.3.x. This means that if you have any “Windows 8” WMI queries, they’ll fail for 8.1. You can use the following query to get around this:

SELECT * FROM Win32_OperatingSystem WHERE (Version LIKE “6.2.%” OR Version LIKE “6.3.%”) AND ProductType=”1”

This query will return both Windows 8 and 8.1, but not Windows 7 (6.1) or Vista (6.0).

image

Convert Camel Case to space delimited Display Name with PowerShell

I’m writing a very rudimentary script that has a need to convert something like “groundFloorMeetingRoom” to “Ground Floor Meeting Room”. Rather than prompt the user to enter this, I decided it’d be easier to just get the script to do it. This turned out to be a fun little exercise, resulting in the CamelCaseToDisplayName function below. Hopefully it can help someone!

function CamelCaseToDisplayName ([string]$inString) {
$newString = ""
$stringChars = $inString.GetEnumerator()
$charIndex = 0
foreach ($char in $stringChars) {
# If upper and not first character, add a space
if ([char]::IsUpper($char) -eq "True" -and $charIndex -gt 0) {
$newString = $newString + " " + $char.ToString()
} elseif ($charIndex -eq 0) {
# If the first character, make it a capital always
$newString = $newString + $char.ToString().ToUpper()
} else {
$newString = $newString + $char.ToString()
}
$charIndex++
}
$newString
}

It’s pretty simple to run, just throw something like this in your script:

$newName = CamelCaseToDisplayName “groundFloorMeetingRoom”

How to use a Domain Controller as an Exchange 2013 DAG Witness Server (Don’t)

If you’re setting up Exchange 2013 in a lab, you may have a requirement to use a domain controller as a File Share Witness (FSW) host.

Obligatory disclaimer: While this is definitely not recommended practise in a production environment, and may have undesirable results, it will probably work. I highly doubt Microsoft support this, though I have been unable to find any concrete evidence on it (frankly, it’s such terrible practise they shouldn’t have to publicise advice against it). If you can come up with a method to avoid following this guide in production, I implore you to do so.

The File Share Witness is used as the winning vote when your DAG has an even number of hosts – the same principle as the quorum drive in a Failover Cluster. This is a file server that all DAG members can read and write (but cannot be a DAG member for obvious reasons).

If you just try to create a DAG and use a domain controller as a FSW, you’ll get this error message:

image

Checking the log file gives the following access denied message, which is less than helpful:

[2013-04-23T23:15:32] WriteError! Exception = System.Management.ManagementException: Access denied
   at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)
   at System.Management.ManagementScope.InitializeGuts(Object o)
   at System.Management.ManagementScope.Initialize()
   at Microsoft.Exchange.Management.Common.WmiWrapper.TryGetSystemDrive(String computerFqdn)
   at Microsoft.Exchange.Management.Common.FileShareWitness.Initialize()
   at Microsoft.Exchange.Management.SystemConfigurationTasks.NewDatabaseAvailabilityGroup.InternalValidate()

image

What’s happening here is that the Exchange server is trying to create a file share on the FSW host, in this case E15DC1. In order to allow this functionality on a domain controller, you must add it to the Exchange Trusted Subsystem group. This is an Active Directory group used internally by Exchange for reading/writing this share, amongst other things. Typically it will only contain Exchange Servers, but go ahead and add your file share witness host to it as well:

 

image

Now comes the bit that makes the security part of me cringe. Exchange Trusted Subsystem (i.e. your Exchange servers) need to be able to create shares on this server and read/write them. As a domain controller has no local security groups, you need to apply this change directory-wide. Add Exchange Trusted Subsystem to your Administrators group:

 

What you’ve done here is made every Exchange server a domain admin. This means that anything running in the context of an Exchange server computer’s user account (E15MB1$, E15MB2$ etc) has full rights over the domain. Do not do this in production!

After giving your DC a reboot (to update its security group membership), Exchange Trusted Subsystem will be able to create shares on it, and your DAG will be able to be created successfully:

image

Add some member servers and Bob’s your uncle. DO NOT DO THIS IN PRODUCTION! I cannot say it enough.

How to Retrieve Mac OS X 10.8 Active Directory Computer Account Password

Active Directory bound Mac OS X computers traditionally stored the computer account credentials in /Library/Preferences/DirectoryService/ActiveDirectory.plist. As of OS X 10.7, this has been moved to the (theoretically) more secure System Keychain. Because of this, a slightly different method has to be employed to extract the computer account password. Fortunately, this is easier than the old plist method. Simply run the following command in Terminal as root (or any sudoer):

security find-generic-password –sw “/Active Directory/MARGIESTRAVEL” /Library/Keychains/System.keychain

This command broken down:

security is the application for accessing keychain information. It is automatically decrypted and presented in a somewhat readable format as though you were using Keychain Access.app.

find-generic-password retrieves the contents of a Keychain item

-w is an option that tells security to only return the password, and to StdOut. By default, security returns generic info to StdOut and returns the password to StdErr. –w “fixes” this.

-s is an option that tells security to return the item of service type <string>.

“/Active Directory/MARGIESTRAVEL” is the name of the keychain item in string format. Obviously this is the Directory Service path to the domain (you can verify by running dscl).

/Library/Keychains/System.keychain is the filesystem path to the System keychain itself.

If you want your script to be redistributable (hint: you do), you can do the following to get the name of the computers’ domain:

dscl localhost –list ”/Active Directory”

This will return the name of the computer’s domain. You could update the command above to implement this like so:

security find-generic-password –w -s “/Active Directory/$(dscl localhost –list '”/Active Directory”)” /Library/Keychains/System.keychain

All we’re doing here is replacing the “MARGIESTRAVEL” component of the name of the keychain item with the command that asks dscl for the name of the computer’s domain. Easy!

P.S. here’s how to get the AD computer account name as well. Doesn’t deserve a blog post, but an interesting little snippet:

security find-generic-password -s "/Active Directory/MARGIESTRAVEL" /Library/Keychains/System.keychain | grep -m 1 "acct" | sed -e 's/"acct"\<blob\>\="//' -e 's/"//' | tr -d ' '

(This one just returns the whole keychain item and looks for the first line containing “Acct”. It then removes all the useless info around the outside of the computer name.