New Add-SPProfileSyncConnection cmdlet seems to ignore NetBIOSDomainNamesEnabled property?

With the release of Service Pack 1 for SharePoint 2010 came a cmdlet called Add-SPProfileSyncConnection which finally allowed the OOB creation of a User Profile Sync connection with Powershell. Prior to this, one would either have to resort to manual creation of a User Profile Sync connection or write up some fairly eloquent custom Powershell to do the job.

As great as Add-SPProfileSyncConnection promised to be, there were some limitations discovered and not much documentation around it. Further, I think I may have found another issue with this new cmdlet – but it only applies in specific cases.

The User Profile service application has a property called NetBIOSDomainNamesEnabled, which is by default set to False. It can be set to True though if the host portion of your Active Directory domain name (e.g. corporate.local) doesn’t match the NetBIOS name of your domain (e.g. CORP). Otherwise, imported user profiles will incorrectly appear in the format corporate\brianl instead of the actual value CORP\brianl.

I’ve noticed that, on a User Profile service app with NetBIOSDomainNamesEnabled set to True, if a sync connection is created using Add-SPProfileSyncConnection and users are subsequently imported, the username format comes through incorrecty – as though NetBIOSDomainNamesEnabled was still set to False.

In the example below, you can see how, in my test domain lalancette.home, with NetBIOSDomainNamesEnabled set to True, my user profiles show up incorrectly as lalancette\username:

After_Add-SPProfileSyncConnection-Highlight

As this is unacceptable and just plain wrong, I decide to blow away the sync connection that was created by the cmdlet, and create one manually, old skool style – with identical parameters (as far as I can control). The connection gets created successfully (confession: I still get a little giddy when this happens), and I then proceed to Start Full Synchronization from Central Admin.

Monitoring user profiles within the service app page, I can actually see the number of profiles drop down to zero after that first full sync. No problem… I run it again, and presto… my user profiles return, and – most importantly – they display in the correct format!
After_ManualProfileSyncConnectionCreation

I’ve run this through several times, and can only attribute it to the connection having been created with the Add-SPProfileSyncConnection cmdlet.

Finally, I’ve confirmed this in all types of post-SP1 farms: SP1 alone, SP1 with the June 2011 CU, and even SP1 with the August 2011 CU.

Has anyone else run into this? Ping me on Twitter: @brianlala

Cheers

Posted in Bugs, Hacks & Workarounds | Tagged | 5 Comments

Powershell-based SP2010 install fails to create Version registry value?

 

As first pointed out in a discussion on my AutoSPInstaller discussion area on Codeplex, and seemingly confirmed in at least one post (that I could find so far), there appears to be an issue with one of the Powershell cmdlets that, when run with a series of other cmdlets, is the equivalent of the SharePoint Products and Technologies Configuration Wizard (AKA psconfigui.exe). The problem can be summed up as follows:

In a regular GUI-based manual installation and configuration, a registry string value called Version gets created at:

HKLM:SOFTWAREMicrosoftShared ToolsWeb Server Extensions14.0

Click to enlarge

However, if you use the SharePoint 2010 Powershell cmdlets (not sure about legacy stsadm-based configs though), the Version string doesn’t get created for some reason! This causes problems with at least one product – Data Protection Manager 2010 (see links above to relevant posts) – as well as some confusion not only as to why this would happen, but what other issues this missing registry entry might cause.

In the meantime, and to set things straight for now, I’m considering just setting the missing registry string value (currently 14.0.0.4762 for the RTM build) by adding a New-ItemProperty command in the AutoSPInstaller. However I’m left feeling that this is kinda less than ideal…

Can anyone else confirm this issue? Have you found any fixes, or are you just using a workaround like the one I’ve suggested?

Cheers
Brian

Posted in Bugs, Hacks & Workarounds | Leave a comment

(Tricks For Successfully) Creating AD Service Connection Points for SharePoint 2010

A few days ago Jie Li posted instructions on how to track SharePoint 2010 installations in an organization by using AD Service Connection points. This sounded really promising, as it could (for example) allow admins to track ‘rogue’ SharePoint installs, or at a minimum just be able to quickly determine where SharePoint’s been installed.

However, I (for one) could not get the GUID sub-container that Jie mentions in his article to be created. I initially thought the problem was that I wasn’t actually using PSConfig (or PSConfigUI), but rather PowerShell commands (through my AutoSPInstaller process). So I ran some tests using SharePoint Foundation (for speed & simplicity) via the GUI, and got some disappointing results:

  • Using the instructions exactly as outlined in the article, no service connection point got created
  • An error was logged in the Application log of the SharePoint server, stating that it had a problem with the ContainerDistinguishedName (as we were instructed to create it in the registry)

Fair enough, I thought. Guided by the error in the event log (which I should have captured for this post – my bad), I then changed the ContainerDistinguishedName value in the registry to something that actually looked like a DistinguishedName:

CN=Microsoft SharePoint Products,CN=System

[click to enlarge]

Click to enlarge

Now, I began to get different errors on subsequent PSConfig attempts – along the lines of “General access denied”. I correlated these to failure audit events on the domain controller, which indicated that, contrary to Jie’s instructions, Write permissions to the Microsoft SharePoint Products container wasn’t enough; we needed something more…

Long story short, it appears that you don’t even need Write permission to the container; it’s sufficient (but necessary) to have the “Create serviceConnectionPoint Objects” permissions (defined on the container object only):

As you can see I’ve gone ahead and granted Authenticated Users the required privileges. Why? Because in order for this feature to be useful (and track as many SharePoint installs as possible), we need installations performed by anyone with a domain account (not just super-users) to register themselves in AD. Further, the super-granular permissions “Create serviceConnectionPoint Objects” (instead of full Write, as initially thought) should mitigate any risk of granting such broad access.

Once I performed these few steps, I ran the SharePoint Products and Technologies Configuration Wizard, and when it finished I could see the new Service Connection Point in Active Directory:

And finally, back to the question about PSConfig being required for all this to work (as opposed to Powershell cmdlets): it appears that yes, only PSConfig does the trick. There’s still something ‘missing’ in the series of Powershell cmdlets that serve to emulate the PSConfig-like activities. Not sure why but stay tuned.

Hope this helps anyone who’s run into similar issues.

Brian

Posted in Hacks & Workarounds, Instructions | 1 Comment

Automating Managed Property Mapping in MOSS 2007 / Search Server 2008

I was recently asked to customize the Advanced Search experience for a Search Server Express 2008 customer. Remember that MSSE is basically WSS 3.0 + the search components from MOSS 2007 (remember that ancient product?). Anyhow this involved enabling the selection of a number of custom fields in the ‘property restrictions’ drop-down. Part of this overall process is mapping Managed Properties to Crawled Properties within the Search Administration area of the shared services provider. I more or less assumed that this would be a GUI-only, manual process for the 20+ properties I was dealing with. However I was faced with applying the changes to at least 4 different environments – not a lot of fun, and likely prone to error by tired eyes and fingers. I wasn’t (and still am not) aware of a way to do this using STSADM.exe, and even scoured the help for STSADM once again in case I’d missed something – no luck.

As is often the case, I stumbled on a neat solution while looking for something else entirely. The folks over at mosssearch.com released a freeware utility called MOSS Search Manager a while back, and it was designed exactly for this purpose. Fantastic! Now all I needed to do was include it in a batch file, give it the names of the managed properties to map (via a text input file), and run the batch file in each environment.

Here is the full script of the batch file. Copy/paste to <something>.cmd, and don’t forget to list all of your managed properties in a file called PropNames.txt in the same directory as the script and MOSSSearchManager.exe.

@ECHO OFF
ECHO - Adding/Mapping Managed Properties...
SET URL=http://yourURL:
SET ContentSource="Content Source Name, e.g. Local Office SharePoint Server sites"
SET InputFile=%~dp0PropNames.txt
ECHO - Getting crawled properties...
FOR /F %%a in (%InputFile%) do (
MOSSSearchManager crawledprop %URL% SharePoint | find /i "ows_%%a"
IF ERRORLEVEL 1 ECHO Crawled property "ows_%%a" not found!
)
ECHO - Getting managed properties...
FOR /F %%a in (%InputFile%) do (
MOSSSearchManager managedprop %URL% SharePoint | find /i "%%a"
IF ERRORLEVEL 1 ECHO Managed property "%%a" not found! & pause
)
pause
ECHO - Mapping properties...
FOR /F %%a in (%InputFile%) do (
ECHO - Mapping property %%a:
MOSSSearchManager mapmprop %URL% %%a %%a
ECHO - Mapping property ows_%%a:
MOSSSearchManager mapmprop %URL% ows_%%a %%a
)
IF ERRORLEVEL 1 pause
ECHO - Initiating Full Crawl...
MOSSSearchManager crawl %URL% %ContentSource% startfull
timeout 10
ECHO - Checking Full Crawl Status...
MOSSSearchManager crawl %URL% %ContentSource% status
pause
EXIT

Although this script was used for Search Server in my case, the search components are shared with MOSS 2007 so the utility/script will work with both products. And yes I suppose I could/should have used Powershell, it wasn’t yet installed on the target server(s) and would have involved additional change management process – not worthwhile for the length of this particular engagement.

So I suppose the lesson is… just when you think it can’t be automated, there may be a solution out there!

Cheers

Posted in Scripts | Leave a comment

High-level steps to SP2010 Demo VHD boot joy

This is sure to raise more questions than it answers… but here goes: how I managed to get the downloadable Information Worker Demo VM to boot straight from VHD (i.e. no host OS). This assumes a fair level of comfort and proficiency in virtual hardware environments, specifically managing virtual hard disks, the Windows registry, commands, etc. Also note that incorrectly performing some of these steps could potentially render your original host OS unbootable, so beware!!

Part I:

  1. Download and extract VHD (duh).
  2. Make sure the target computer/laptop/server is already running either Windows 2008 R2 or Windows 7. VHD booting requires the new boot loader from either OS to mount a VHD during boot.
  3. Mount the VHD in your fave x64-guest-compatible virtualization platform (other than Hyper-V, I’ve also had success with VirtualBox, others have gotten VMWare to work too after VHD conversion).
  4. Boot the demo VM as you normally would. Once up, you can optionally disable the demo services for faster boot & operation until the VHD is in its final self-booting state.
  5. Upgrade the OS of the IW Demo VM from Win2008 to Win2008 R2 – this is required for VHD boot. Note that you’ll need to run a few adprep commands first, since the demo VM is a domain controller.
  6. Modify your original (physical) boot configuration (using BCDEDIT.exe) to include the path to your newly-upgraded VHD. Sample steps for doing so can be found here and here.

If you’re still with me, at this point you’ll have a freshly-upgraded VM and VHD file, almost ready for VHD boot. Now we’ll need to make sure it actually boots (as opposed to blue-screening). You can definitely try it out now – if it works great! If not (more likely), then read on for Part II.

Part II:

  1. You’ll most likely need to download and ‘inject’ the driver for the hard disk controller for your target hardware. Why? Because apparently the OS that’s booting from the VHD needs to communicate with the hardware the same way your current OS does, and if it can’t do so during boot, it just fails. For example, for most Intel-based chipsets/controllers, you’ll need the Matrix Storage driver. Further, you’ll need to modify the registry so that the VM knows to load this driver at boot. This is probably the trickiest part of this whole process. The steps outlined here are a good starting point, of course you’ll need to modify them to include the registry entries for your own hardware… Here are some basic steps that worked for me:
    1. Download the controller driver, extract it, and copy the extracted files to both C:Windowsinf and C:Windowssystem32drivers on the VM image (I know this is overdoing it, but it works)
    2. Export the HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlCriticalDeviceDatabase on your original (host) OS subtree to a file, like reg1.reg – again, we probably don’t need the whole thing but in a rush it will get us what we need in terms of boot driver config
    3. Export the HKEY_LOCAL_MACHINESYSTEMCurrentControlSetservices<drivername> registry subtree on the original (host) OS to reg2.reg. In my case <drivername> was iaStor for the Intel RAID Controller.
    4. Import the two exported registry file into your demo VM. Note that after doing this, you may only be able to do VHD boot going forward, and that booting again while in a VM may not work!
  2. Try (re-try) booting your VHD
  3. If it still fails, you might want to check that:
    1. You have enough free space on your host disk for the VHD to expand to its full capacity when booting (default is ~127GB for the demo VM)
    2. Your VHD isn’t on a compressed or encrypted volume
    3. You’ve actually applied the right hard disk controller driver to the VHD image (hit ‘F8’ during boot to enable troubleshooting options)

Assuming you haven’t given up by this point, and you’ve actually managed to get the VHD to boot, you can now install all the rest of the required drivers (video, LAN, peripherals etc.), just as you would for a regular OS running on the bare metal – because after all, it is running on the bare metal (except for the virtualized boot hard disk). Also, you can re-enable all of your services (if you disabled them in step 4.), but disable the Hyper-V guest services (since we’re no longer running in Hyper-V). Finally, you’ll want to apply the SharePoint 2010 pre-requisite hotfix for Win2008 R2 to your demo machine – since it was upgraded from plain Win2008, it would only have the hotfix for that particular OS applied.

Good luck!!

References:

Posted in Hacks & Workarounds, Instructions | Leave a comment

Powershell script to enable/disable services in SP2010 Demo VM

If any of you have had the chance to play around with Microsoft’s recent public release of the Information Worker Demo VM, you’ll notice that a) it has pretty much everything thrown in in terms of the Office suite of server/client products and b) it’s a hog! At idle, the VM will start to consume almost 10GB RAM (combined physical and virtual/paging) within minutes of booting up. For developers and sysadmins used to running (2 or 3) 32-bit MOSS2007 Virtual PCs concurrently on your laptop, the new resource requirements for SP2010 can be quite a shock. How can we trim and optimize the resources the demo VM uses? By turning off services we don’t immediately need…

For example, if you want to develop/demo SharePoint 2010 stuff only, but don’t care about Office Communications Server, you can turn all of these services (and the supporting SQL instance) off, and free up quite a bit of RAM. However, you might want to change this in a different scenario, so that only the OCS services are running but the SharePoint stuff is off. This could get pretty tedious if we were simply using the Services MMC each time!

Using a Powershell script though, we can quickly enable/start or disable/stop different services on our demo VM, just in time for its intended use at any particular time. The script below can easily be further customized to allow for greater granularity over what services are controlled, etc. Consider it a starting point towards getting only the services you want running at any particular time on a machine with limited resources.

[UPDATE] – turns out Emmanuel Bergerat had already released scripts with very similar functionality, way back in November! Definitely check these out for another approach to freeing up resources on a SP2010 install.

Hope you find it useful! Oh and watch the line breaks and double quotes when copying/pasting…


## Stop-Start-Services.ps1 by Brian Lalancette
## Originally intended for SP2010 IW Demo VM

Function StopUnneededServices
{
Write-Host -ForegroundColor Blue "- Stopping services..."
#Permanent service stoppage - you likely wont need these in the demo VM
$ServicesToSetManual = ("Spooler",`
"AudioSrv",`
"TabletInputService",`
"UxSms",`
"ftpsvc",`
"MSSQLFDLauncher",`
"SQLSERVERAGENT")
$ServicesToDisable = ("WPDBusEnum",`
"WerSvc",`
"WSearch")
Write-Host -ForegroundColor Blue "- Setting some unneeded services to Manual start..."
ForEach ($SvcName in $ServicesToSetManual)
{
If (Get-Service -Name $SvcName -ErrorAction SilentlyContinue)
{
Stop-Service -Name $SvcName -Force
Set-Service -Name $SvcName -StartupType Manual
Write-Host -ForegroundColor Blue " - Service $SvcName is now set to Manual start"
}
}
Write-Host -ForegroundColor Blue "- Disabling some unneeded services..."
ForEach ($SvcName in $ServicesToDisable)
{
If (Get-Service -Name $SvcName -ErrorAction SilentlyContinue)
{
Stop-Service -Name $SvcName -Force
Set-Service -Name $SvcName -StartupType Disabled
Write-Host -ForegroundColor Blue " - Service $SvcName is now disabled."
}
}
}

Function StopSPServices
{
#Temporary SP demo service stoppage; use actual service name, not display (long) name
$ServicesToDisable = ("FASTSearchService",`
"FASTSearchMonitoring",`
"ProjectEventService14",`
"ProjectQueueService14",`
"WebAnalyticsService",`
"SPAdminV4",`
"SPTimerV4",`
"SPTraceV4",`
"SPAdminV4",`
"SPUserCodeV4",`
"OSearch14",`
"FIMService",`
"FIMSynchronizationService",`
"MSSQLSERVER",`
"MSSQLServerOLAPService",`
"MSDtsServer100",`
"ReportServer",`
"SQLWriter",`
"W3SVC",`
"IISADMIN")
Write-Host -ForegroundColor Blue "- Disabling SP demo services..."
ForEach ($SvcName in $ServicesToDisable)
{
If (Get-Service -Name $SvcName -ErrorAction SilentlyContinue)
{
Stop-Service -Name $SvcName -Force
Set-Service -Name $SvcName -StartupType Disabled
Write-Host -ForegroundColor Blue " - Service $SvcName is now disabled."
}
}
Write-Host -ForegroundColor White "- Finished disabling SP demo services."
}

Function StopFASTServices
{
#Temporary FAST service stoppage; use actual service name, not display (long) name
$ServicesToDisable = ("FASTSearchService",`
"FASTSearchMonitoring")
Write-Host -ForegroundColor Blue "- Disabling FAST services..."
ForEach ($SvcName in $ServicesToDisable)
{
If (Get-Service -Name $SvcName -ErrorAction SilentlyContinue)
{
Stop-Service -Name $SvcName -Force
Set-Service -Name $SvcName -StartupType Disabled
Write-Host -ForegroundColor Blue " - Service $SvcName is now disabled."
}
}
Write-Host -ForegroundColor White "- Finished disabling FAST services."
}

Function StopOCSServices
{
If (Get-Service -Name 'MSSQL$RTC' -ErrorAction SilentlyContinue)
{
Write-Host -ForegroundColor Blue "- Disabling OCS demo services..."
Set-Service -Name 'MSSQL$RTC' -StartupType Disabled
Stop-Service -Name 'MSSQL$RTC'
Get-Service | ?{$_.DisplayName -like "Office Communications*"} | Set-Service -StartupType Disabled
Get-Service | ?{$_.DisplayName -like "Office Communications*"} | Stop-Service
Write-Host -ForegroundColor White "- Finished disabling OCS services."
}
}

Function StartSPServices
{
$ServicesToSetAutomatic = ("FASTSearchService",`
"FASTSearchMonitoring",`
"MSSQLSERVER",`
"MSSQLServerOLAPService",`
"MSDtsServer100",`
"ReportServer",`
"SQLWriter",`
"W3SVC",`
"ProjectEventService14",`
"ProjectQueueService14",`
"WebAnalyticsService",`
"SPAdminV4",`
"SPTimerV4",`
"SPTraceV4",`
"SPAdminV4",`
"SPUserCodeV4",`
"FIMService",`
"FIMSynchronizationService",`
"OSearch14",`
"IISADMIN")
Write-Host -ForegroundColor Blue "- Re-enabling SP demo services..."
ForEach ($SvcName in $ServicesToSetAutomatic)
{
If (Get-Service -Name $SvcName -ErrorAction SilentlyContinue)
{
Set-Service -Name $SvcName -StartupType Automatic
Start-Service -Name $SvcName
Write-Host -ForegroundColor Blue " - Service $SvcName is now set to Automatic start"
}
}
Write-Host -ForegroundColor White "- Finished re-enabling SP demo services."
}

Function StartOCSServices
{
If (Get-Service -Name 'MSSQL$RTC' -ErrorAction SilentlyContinue)
{
Write-Host -ForegroundColor Blue "- Re-enabling OCS demo services..."
Set-Service -Name 'MSSQL$RTC' -StartupType Automatic
Start-Service -Name 'MSSQL$RTC'
Get-Service | ?{$_.DisplayName -like "Office Communications*"} | Set-Service -StartupType Automatic
Get-Service | ?{$_.DisplayName -like "Office Communications*"} | Start-Service
Write-Host -ForegroundColor White "- Finished re-enabling OCS demo services."
}
}

Function ChooseOption
{
$Choice = Read-Host "Please select:`n`
(1) - Stop ALL demo services`n`
(2) - Stop OCS demo services`n`
(3) - Stop SharePoint demo services`n`
(4) - Stop FAST services`n`
(5) - Start ALL demo services`n`
(6) - Start OCS demo services`n`
(7) - Start Sharepoint demo services`n`
(0) - QUIT`n`
Choice"

Switch ($Choice)
{
"1" {StopUnneededServices;StopSPServices;StopOCSServices;ChooseOption}
"2" {StopUnneededServices;StopOCSServices;ChooseOption}
"3" {StopUnneededServices;StopSPServices;ChooseOption}
"4" {StopFASTServices;ChooseOption}
"5" {StartSPServices;StartOCSServices;ChooseOption}
"6" {StartOCSServices;ChooseOption}
"7" {StartSPServices;ChooseOption}
"0" {break}
default {Write-Host -ForegroundColor Red "- Please select a valid option...";ChooseOption}
}
If ($Choice -eq "0") {break}
}

$Choice
If ($Choice -ne "0") {ChooseOption}

Write-Host "Press any key to exit..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

Posted in Scripts | 1 Comment