Pages

Friday, December 7, 2012

SP2010 User Profile Service Application Setup and NetBIOSDomainNamesEnabled Issues

Have you ever set up SharePoint User Profile sync and saw crazy things happen and thought yourself really luckly to stumble up on blogs talking about setting NetBIOSDomainNamesEnabled to true when you have a different NetBIOS and FQDN names?

Only to find out weeks later that things still look crazy.. like users from one domain are coming across with 2 different domain names. or that users who started out with one domain name have now switched to a different domain name and now perhaps their MySite link doesn't work any more?

It was only through a call to MS Support that I found out that

If you've already created your AD connections before you set NetBIOSDomainNamesEnabled, you MUST delete & recreate your AD connections. 

This was not documented anywhere on technet. The reference the MS Support person gave me was hidden this MSDN blog:
http://blogs.msdn.com/b/russmax/archive/2010/03/20/sharepoint-2010-provisioning-user-profile-synchronization.aspx 

So, to repeat, if your Domain NETBIOS name is different from the FQDN of the domain...

1. Delete your AD Connections 

2. Set NetBIOSDomainNamesEnabled to true using Powershell

$upa = Get-SPServiceApplication | where {$_.TypeName -eq "User Profile Service Application"}
$upa.NetBiosDomainNamesEnabled = $true
$upa.Update()

3. Reset IIS & restart OWSTimer just to be safe


4. Recreate AD Connection(s)


5. Run Full import at least twice


6. Run incremental sync to get colleagues re-populated


If you are in the same situation I was in where your could NOT just delete connections b/c users had uploaded pictures and profile info these are some scripts that I used to save off and restore the data.

Export User Profile Properties

Export Colleagues 

Add Colleagues





Powershell - Export Colleagues


#Setup variables
$mysiteurl = "YOUR MYSITE URL"
$mysite = Get-SPSite $mysiteurl
$context = Get-SPserviceContext $mysite
$profilemgr = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$profiles = $profilemgr.GetEnumerator()
Write-Host "Loop through users and export data"
$stream = [System.IO.StreamWriter] "ColleaguesExport.csv"
$stream.WriteLine("User, #, Colleagues")

function HasValue($str)
{
if($str) {$true} else {$false}
}

$colleagues = 0;

#loop through all profiles
foreach($usr in $profiles)
{

if ($usr.Colleagues.GetItems().Count -gt 0) 
{
$colleagues++
$stream.Write($usr["accountname"])
$stream.Write(",")
$stream.Write($usr.Colleagues.GetItems().Count)
$stream.Write(",")
foreach($col in $usr.Colleagues.GetItems())
{
$stream.Write($col.Profile["accountname"])
$stream.Write(" | ")
}
$stream.WriteLine()

}

}


Write-Host "Colleagues:" $colleagues

$stream.Close()


Powershell - Add Colleagues


param (  
    #[Parameter(Mandatory=$true)]
    [string] $user,
    #[Parameter(Mandatory=$true)]
    [string] $userToAdd
)

#Setup variables
$groupType = [microsoft.office.server.userprofiles.colleaguegrouptype]::General
$privacy = [microsoft.office.server.userprofiles.privacy]::Public
$mysiteurl = "http://employees.benefitmall.com"
$mysite = Get-SPSite $mysiteurl
$context = Get-SPserviceContext $mysite
$profilemgr = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)


$firstuser = $profilemgr.GetUserProfile($user)
$seconduser = $profilemgr.GetUserProfile($userToAdd)

if(($firstuser) -and ($seconduser))
{
$firstuser.Colleagues.CreateWithoutEmailNotification($seconduser, $groupType, "General", $false, $privacy)
}
else
{
if(!$firstuser) {Write-Host "$usera does not exist"}
if(!$seconduser) {Write-Host "$userToAdd does not exist"}
}

Powershell - Export User Profile Properties

Useful if you need to save off this data before deleting/re-creating user profiles.


#Setup variables
$mysiteurl = "YOUR MYSITE URL"
$mysite = Get-SPSite $mysiteurl
$context = Get-SPserviceContext $mysite
$profilemgr = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$profiles = $profilemgr.GetEnumerator()
Write-Host "Loop through users and export data"
$stream = [System.IO.StreamWriter] "PropertiesExport.csv"
$stream.WriteLine("User, pic, ask me about, cell, office location, timezone, assistant, projects, skills, schools, birthday, certs")


function HasValue($str)
{
if($str) {$true} else {$false}
}
$bios = 0;
$pics = 0;
$aboutme = 0;
$cell = 0;
$location = 0;
$timezone = 0;
$assistant = 0;
$proj = 0;
$skills = 0;
$schools = 0;
$birthday = 0;
$certs =0;
$colleagues = 0;

#loop through all profiles
foreach($usr in $profiles)
{

if((HasValue($usr["bio"])) -or `
(HasValue($usr["PictureUrl"])) -or `
(HasValue($usr["SPS-Responsibility"]))  -or `
(HasValue($usr["CellPhone"]))  -or `
(HasValue($usr["SPS-Location"]))  -or `
(HasValue($usr["SPS-TimeZone"]))  -or `
(HasValue($usr["Assistant"]))  -or `
(HasValue($usr["SPS-PastProjects"]))  -or `
(HasValue($usr["SPS-Skills"]))  -or `
(HasValue($usr["SPS-Schools"]))  -or `
(HasValue($usr["SPS-Birthday"]))  -or `
(HasValue($usr["Certifications"])))
{


$stream.Write($usr["accountname"])
$stream.Write(",")
if(HasValue($usr["PictureUrl"])){$stream.Write($usr["PictureUrl"]); $pics++ } 
$stream.Write(",")
if(HasValue($usr["SPS-Responsibility"])){$stream.Write($usr["SPS-Responsibility"]); $aboutme++}
$stream.Write(",")
if(HasValue($usr["CellPhone"])){$stream.Write($usr["CellPhone"]); $cell++ }
$stream.Write(",")
if(HasValue($usr["SPS-Location"])){$stream.Write($usr["SPS-Location"]); $location++ }
$stream.Write(",")
if(HasValue($usr["SPS-TimeZone"])){$stream.Write($usr["SPS-TimeZone"]); $timezone++ }
$stream.Write(",")
if(HasValue($usr["Assistant"])){$stream.Write($usr["Assistant"]); $assistant++ }
$stream.Write(",")
if(HasValue($usr["SPS-PastProjects"])){$stream.Write($usr["SPS-PastProjects"]); $proj++}
$stream.Write(",")
if(HasValue($usr["SPS-Skills"])){$stream.Write($usr["SPS-Skills"]); $skills++}
$stream.Write(",")
if(HasValue($usr["SPS-Schools"])){$stream.Write($usr["SPS-Schools"]); $schools++ }
$stream.Write(",")
if(HasValue($usr["SPS-Birthday"])){$stream.Write($usr["SPS-Birthday"]); $birthday++ }
$stream.Write(",")
if(HasValue($usr["Certifications"])){$stream.Write($usr["Certifications"]); $certs++ }
$stream.WriteLine()


}

if(HasValue($usr["bio"]))
{
$biostream.WriteLine($usr["accountname"])
$biostream.WriteLine($usr["bio"]) 
$biostream.WriteLine("*****")
$biostream.WriteLine("")
$bio++
}
}
Write-Host "Bios:" $bio
Write-Host "Pics:" $pics
Write-Host "Ask Me About:" $aboutme
Write-Host "Mobile:" $cell
Write-Host "Office Location:" $Location
Write-Host "TimeZone:" $timezone
Write-Host "Assistant:" $assistant
Write-Host "Past Projects:" $proj 
Write-Host "Skills:" $skills 
Write-Host "Schools:" $schools 
Write-Host "Birthdays:" $birthday 
Write-Host "Certifications:" $certs 
Write-Host "Colleagues:" $colleagues

$stream.Close()

Tuesday, September 11, 2012

AutoSPInstaller error - Cannot convert value "System.Object[]" to type "System.Xml.XmlDocument"

AutoSPInstaller is a godsend for SharePoint installations. (Also, wow, I just typed “AutoSPInstaller” and Windows Live Writer automatically linked to the codplex page. Crazy!) However, the other day I ran into a situation where I’d run the script on one environment and took the same script, updated usernames & passwords, and ran it in a new environment only to find that the script was erroring with the following output:

- Using standard Input File.
- Checking for Powershell 2.0...
- OK.
Transcript started, output file is C:\Users\SVC_SP_Admin\Desktop\AutoSPInstalle
r-2010-06-11_2-27.rtf
- Reading Input File D:\SP2010\Scripted\\SetInputs.xml...
Cannot convert value "System.Object[]" to type "System.Xml.XmlDocument". Error:
"An error occurred while parsing EntityName. Line 25, position 24."
At D:\SP2010\Scripted\AutoSPInstaller.ps1:22 char:18
+ $xmlinput = [xml] <<<<  (get-content $InputFile)
    + CategoryInfo          : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException

You cannot call a method on a null-valued expression.

What the heck? I just used the same input in another environment and it worked fine!

Thankfully Google once again saved my butt when I found this post noting that an “&” in a password caused the issue. Hollahh!! That was it. The new passwords in my new environment had crazy &s, so we updated the passwords and everything worked fine. Just wanted to let you guys know about this to hopefully save you the hour of going cross-eyed double checking your input.xml file!

Thursday, March 29, 2012

Creating a New Site Collection from a Custom Web Template in Powershell


I just wasted a bunch of time re-figuring this out b/c I had forgotten, so here is how you do it.

1. Get your web template name


Get-SPWebTemplate | format-table name


This will give you the full name of your custom web template, which will be {[Template Feature GUID]}#[TemplateName]}

2. Create the site collection with powershell:


New-SPSite -url [Your URL] -
ownerAlias [Site Collection Admin Doman\Username] -Template {Web Template Name}

Monday, November 14, 2011

A little facelift…

Figured it was time to streamline:
  • New URL: http://freakingsharepoint.com/
  • New look – testing out Blogger’s Dynamic Views – not completley sold yet - Nope. Hated it. Going back to a basic template!

Other interesting tidbits to mark this juncture:

Thanks for reading and hope to discover more SharePoint goodness to share with you guys!