IT Ramblings

Ramblings from an IT manager and long time developer.

Office 365 – Single Sign-On for SharePoint, Skydrive, CRM, etc. via Smart Links

Synopsis: One of the biggest problems I have seen with Office 365 is ease in accessibility to all of the Office365 resources.  As pointed out on many of the Microsoft forums, SharePoint, CRM, Skydrive, etc. do not automatically complete a single-sign on request when browsing the website.

Problem: When a user browses for example, the user is prompted to enter in their email address.  What a user expects is that they should automatically be logged in and see sharepoint when navigating to  Additionally, for whatever reason, users cannot remember the website address to  Instead, they want to do something like

Solution: Create name branded “fancy URLs” that will complete an idp claim to give the user a true SSO experience.



  1. Open up Internet Explorer
  2. Navigate to
    Sign into Office 365
  3. Press F12 to open up the developer tools console (I am running IE 11, the console looks way different than previous versions of IE)
    Sign into Office 365 - Developer Console
  4. Scroll down and select the icon that looks like a little WiFi antenna
    Sign into Office 365 - Developer Console - Network
  5. Click the green play button
    Sign into Office 365 - Developer Console - Network - Start Capture
  6. Type in your email address as you would to login to sharepoint (
  7. You should be redirected to your ADFS server and inside the network console, you should see a link like………………  Copy this link into notepad.
    Office 365 - Federated URL
  8. Remove the extra stuff from the debug console
    Office 365 - Federated URL - Notepad

    Office 365 - Federated URL - Cleaned - Notepad
  9. Remove everything from cbcxt=….. to wa=wsignin1.0
    Office 365 - Federated URL - cbcxt removed
  10. Remove the ct%3D1386214464%26 and bk%3D1386214464%26 parameters
    Office 365 - Federated URL - ct and bk removed
  11. Next, open up another new notepad document named index.html and paste the following text into it
    1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      ""><html xmlns=""><head>
      <meta http-equiv=”refresh” content=”0; url= link goes here” />



      Redirect to URL template

  12. Replace link goes here with your new smart link and save the document.
    Redirect to federated URL
  13. Upload the index.html file to one of your your webservers
  14. Create a new A record called pointing to your webserver
  15. Now when a user browses, the user will automatically be redirected to your secure ADFS Proxy and authenticate automatically.

You will need to repeat the steps above for each of the Office 365 products your company uses.  The federated addresses do change, so you will have to follow all of the steps over again for each Smart Link you wish to create.


Here is an official article on creating smart links:

How To: Set up Time Machine for Multiple Macs on FreeNAS (

This is copied from here

FreeNAS is awesome. Also, FreeNAS is hard... I recently switched from a Synology device, and while I am already appreciating the increase in functionality and power, it's certainly not as easy to do some basic tasks. One of those tasks is setting up a Time Machine share where all of my household Macs can back up. Between reading the tutorials and giving some trial and error myself, I think I have come up with a good solution. And before I get started with the step by step guide, let me reiterate one thing: Permissions, Permissions, Permissions! If you ever find yourself banging your head against a wall because something in FreeNAS isn't working as you expect it to, the likely culprit is permissions. Once you wrap your brain around them, though, things become more simple. Hopefully this guide helps put a foundation around that.

The Default FreeNAS Home Screen

This article assumes that you have FreeNAS already up and running on your network and that you're able to connect to the main home screen with your web browser. I recommend setting it a static IP, as well. Our first step will be to create a group / user for Time Machine backups.


Under the "Account" section on the left, click "Groups," and then click "Add Group."


You don't need to change the default value for the group ID, and put something like "time-machine" for the group name. Leave everything as default and click OK.

The next step is to create a ZFS dataset where we're going to put the Time Machine backups. The dataset must be on a ZFS volume. I'm assuming you have already created a ZFS volume with your disks here, but if you haven't stop reading this guide and go read the FreeNAS ZFS documentation here. If you have already created the volume, create a dataset. Datasets can be nested inside of other datasets so I actually have one dataset called "Backup" and inside of that one, I have one callled "Time-Machine" ~ it really just depends on how you want things set up.


After you enter the name, "Time-Machine", leave all of the default values alone. The below screenshot shows how I have "Time-Machine" nested inside of my Backup dataset.


So now we have a dataset. This is going to be where all of our Time Machine backups get saved. The next step is the most important and the one that has bitten me before... so don't forget it. We need to change the permissions on the "Time-Machine" dataset. Recall that we initially created a group called "time-machine" - we are now going to set things up such that any user in the "time-machine" group can write to the "Time-Machine" dataset. Click on the "Time-Machine" dataset and then click on the icon with a key on it to change its permissions.


When you click that, a permissions dialog box will pop up.


I chose not to change the default user owner of "root." However, definitely change the group owner. In the drop down box, the "time-machine" group that we previously created should be selectable. Click that and then make sure to have the boxes checked as I have in the image above. We want any user in the group to have read / write / execute privileges.

Click the "Change" button to have the new permissions take effect. Now it's time to create a user for the Time Machine backup. I believe it is best to create a separate user for each computer (and I'll explain why at the end of the post) so just create users that reflect that computer. For example, the user I'm creating is called "kevinmacbookair."


Once again, you navigate over to the left column to create a new user. Leave the "User ID" field as the default. Give your username a simple lowercase name like mine. Uncheck the box about creating a new primary group for the user. Instead, go to the drop down list and select "time-machine" in there. In the full name, put a descriptive name. Type in a password, and then you're good to go.

So what we've done so far is created a group called "time-machine" which has full access to the "Time Machine" dataset. Next we added a user that is part of the "time-machine" group. Easy! The last thing we need to do is create an AFP (Apple Filing Protocol) share that will broadcast this over the network so your Mac can see it. To do this, click the "Sharing" link on the column on the far left and click the button to create a new AFP share.


Name your share something you like, and then use the file browser to make sure that the "Path" is set to the ZFS dataset that we created for our Time Machine backups. Next, for the "Allow List" and "Read-write Access" fields, we want to put the group that we created, "time-machine" ~ however, because it's a group and not a user, we need to put the "@" symbol in front of it: "@time-machine". Next make, sure the "Time Machine" box is checked. Finally, take a look at those check boxes of privileges and make sure they match what's listed above. Then click OK. At this point, we're done with everything on the FreeNAS system. It's now time to set up Time Machine on the Mac!


On the Mac, just open up the Time Machine preferences, and if you go to select a disk, you should find the one we created there! It will ask you for a username / password, and you want to make sure you enter the machine-specific one we created in FreeNAS, not your OS X username / password.


You should be golden! If you want to add more than one computer, you don't need to add any new AFP shares or anything like that. Just create new users for each machine, and make sure that each user is part of the "time-machine" group that we created earlier. The final improvement to make this work even better would be for us to cap how much space each computer has to back up. For example, my MacBook Air has 256GB of space, and anything on my MacBook Air is also on my other machines so I really wouldn't want to give it more than 300GB of usable space for historical backups. Time Machine will automatically delete the older ones if it runs out of room. On the contrary, my MacBook Pro is loaded up with all of my important data and I might want to give it 2x the space of its SSD. Right now there isn't a great way to do this for multiple Macs in FreeNAS, but a feature is coming soon that will make it easy! This feature is per-user quotas. This will allow us to specify the maximum amount of space each user is allowed.

I hope this guide was useful!

Lanuching Visual Studio Android Emulator from the command line

Quick command line to launch the Visual Studio Android Emulator for Lollipop

XDE\\xde.exe /sku Android /displayName "VS Emulator 5\" 
Lollipop (5.0) XXHDPI Phone" /memSize 2048 /diagonalSize 5 /video 
"1080x1920" /vhd 
​ners\Local\Devices\vhd\5_Lollipop_(5.0)_XXHDPI_Phone\image.vhd" /name 
"VS Emulator 5-inch Lollipop (5.0) XXHDPI Phone.%USERNAME%" 

Cisco AnyConnect

Cisco AnyConnect is an SSL VPN client that provides reliable and easy-to-deploy encrypted (SSL) network connectivity for Windows.

Typically, the Cisco AnyConnect client would be downloaded from the VPN site, but the version currently available from that location is not compatible with current versions of Windows 7 and Windows 8 and will not function properly due to Microsoft Windows security updates.

Download Link

AnyConnect-3.1.02026.exe (3.9MB)

This is a bunch of command line tools for troubleshooting Microsoft Active Directory. Shared from the website.

FSMO Roles
ntdsutilroles Connections "Connect to server %logonserver%" Quit "selectOperation Target" "List roles for conn server" Quit Quit Quit
[JDH: This is really a series of steps, not a single command

Domain Controllers
Nltest /dclist:%userdnsdomain%

Domain Controller IP Configuration
for /f %i in (‘dsquery server -domain %userdnsdomain% -o rdn’) do psexec \\%i ipconfig /all

Stale computer accounts
dsquery computer domainroot -stalepwd 180 -limit 0

Stale user accounts
dsquery user domainroot -stalepwd 180 -limit 0

Disabled user accounts
dsquery user domainroot -disabled -limit 0

AD Database disk usage
for /f %i in (‘dsquery server -domain %userdnsdomain% -o rdn’) do dir \\%i\admin$\ntds

Global Catalog Servers from DNS
dnscmd %logonserver% /enumrecords %userdnsdomain% _tcp | find /i "3268"

Global Catalog Servers from AD
dsquery * "CN=Configuration,DC=forestRootDomain" -filter "(&(objectCategory=nTDSDSA)(options:1.2.840.113556.1.4.803:=1))"

Users with no logon script
dsquery * domainroot -filter"(&(objectCategory=Person)(objectClass=User)(!scriptPath=*))"-limit 0 -attr sAMAccountName sn givenName pwdLastSet distinguishedName

User accounts with no pwd required
dsquery * domainroot -filter "(&(objectCategory=Person)(objectClass=User)(userAccountControl:1.2.840.113556.1.4.803:=32))"

User accounts with no pwd expiry
dsquery * domainroot -filter"(&(objectCategory=Person)(objectClass=User)(userAccountControl:1.2.840.113556.1.4.803:=65536))"

User accounts that are disabled
dsquery * domainroot -filter "(&(objectCategory=Person)(objectClass=User)(userAccountControl:1.2.840.113556.1.4.803:=2))"

DNS Information
for /f %i in (‘dsquery server -domain %userdnsdomain% -o rdn’) do dnscmd %i /info

DNS Zone Detailed information
dnscmd /zoneinfo %userdnsdomain%

Garbage Collection and tombstone
dsquery * "cn=Directory Service,cn=WindowsNT,cn=Services,cn=Configuration,DC=forestRootDomain" -attrgarbageCollPeriod tombstoneLifetime

Netsh authorised DHCP Servers
netsh dhcp show server

DSQuery authorised DHCP Servers
Dsquery * "cn=NetServices,cn=Services,cn=Configuration, DC=forestRootDomain" -attr dhcpServers

DHCP server information
netsh dhcp server \\DHCP_SERVER show all

DHCP server dump
netsh dhcp server \\DHCP_SERVER dump

WINS serer information
Netsh wins server \\WINS_SERVER dump

Group Policy Verification Tool
gpotool.exe /checkacl /verbose

AD OU membership
dsquery computer -limit 0

AD OU membership
dsquery user -limit 0

List Service Principal Names
for /f %i in (‘dsquery server -domain %userdnsdomain% -o rdn’) do setspn -L %i

Compare DC Replica Object Count
dsastat ?s:DC1;DC2;… ?b:Domain ?gcattrs:objectclass ?p:999

Check AD ACLs
acldiag dc=domainTree

NTFRS Replica Sets
for /f %i in (‘dsquery server -domain %userdnsdomain% -o rdn’) do ntfrsutl sets %i

for /f %i in (‘dsquery server -domain %userdnsdomain% -o rdn’) do ntfrsutl ds %i

Domain Controllers per site
Dsquery * "CN=Sites,CN=Configuration,DC=forestRootDomain" -filter (objectCategory=Server)

DNS Zones in AD
for /f %i in (‘dsquery server -o rdn’) do Dsquery * -s %i domainroot -filter (objectCategory=dnsZone)

Enumerate DNS Server Zones
for /f %i in (‘dsquery server -o rdn’) do dnscmd %i /enumzones

Subnet information
Dsquery subnet ?limit 0

List Organisational Units
Dsquery OU

ACL on all OUs
For /f "delims=|" %i in (‘dsquery OU’) do acldiag %i

Domain Trusts
nltest /domain_trusts /v

Print DNS Zones
dnscmd DNSServer /zoneprint DNSZone

Active DHCP leases
For /f %i in (DHCPServers.txt) do for /f "delims=- " %j in (‘"netshdhcp server \\%i show scope | find /i "active""’) do netsh dhcp server\\%i scope %j show clientsv5

DHCP Server Active Scope Info
For /f %i in (DHCPServers.txt) do netsh dhcp server \\%i show scope | find /i "active"

Resolve DHCP clients hostnames
for /f "tokens=1,2,3 delims=," %i in (Output from ‘Find Subnets fromDHCP clients’) do @for /f "tokens=2 delims=: " %m in (‘"nslookup %j |find /i "Name:""’) do echo %m,%j,%k,%i

Find two online PCs per subnet
Echo. > TwoClientsPerSubnet.txt & for /f "tokens=1,2,3,4delims=, " %i in (‘"find /i "pc" ‘Output from Resolve DHCP clientshostnames’"’) do for /f "tokens=3 skip=1 delims=: " %m in (‘"Find /i /c"%l" TwoClientsPerSubnet.txt"’) do If %m LEQ 1 for /f %p in (‘"ping -n1 %i | find /i /c "(0% loss""’) do If %p==1 Echo %i,%j,%k,%l

AD Subnet and Site Information
dsquery * "CN=Subnets,CN=Sites,CN=Configuration,DC=forestRootDomain" -attr cn siteObject description location

AD Site Information
dsquery * "CN=Sites,CN=Configuration,DC=forestRootDomain" -attr cn description location -filter (objectClass=site)

Printer Queue Objects in AD
dsquery * domainroot -filter "(objectCategory=printQueue)" -limit 0

Group Membership with user details
dsget group "groupDN" -members | dsget user -samid -fn -mi -ln -display -empid -desc -office -tel -email -title -dept -mgr

Total DHCP Scopes
find /i "subnet" "Output from DHCP server information" | find /i "subnet"

Site Links and Cost
dsquery * "CN=Sites,CN=Configuration,DC=forestRootDomain" -attr cn costdescription replInterval siteList -filter (objectClass=siteLink)

Time gpresult
timethis gpresult /v

Check time against Domain
w32tm /monitor /computers:ForestRootPDC

Domain Controller Diagnostics
dcdiag /s:%logonserver% /v /e /c

Domain Replication Bridgeheads
repadmin /bridgeheads

Replication Failures from KCC
repadmin /failcache

Inter-site Topology servers per site
Repadmin /istg * /verbose

Replication latency
repadmin /latency /verbose

Queued replication requests
repadmin /queue *

Show connections for a DC
repadmin /showconn *

Replication summary
Repadmin /replsummary

Show replication partners
repadmin /showrepl * /all

All DCs in the forest
repadmin /viewlist *

ISTG from AD attributes
dsquery * "CN=NTDS Site Settings,CN=siteName,CN=Sites,CN=Configuration,DC=forestRootDomain" -attr interSiteTopologyGenerator

Return the object if KCC Intra/Inter site is disabled for each site
Dsquery site | dsquery * -attr * -filter "(|(Options:1.2.840.113556.1.4.803:=1)(Options:1.2.840.113556.1.4.803:=16))"

Find all connection objects
dsquery * forestRoot -filter (objectCategory=nTDSConnection) ?attr distinguishedName fromServer whenCreated displayName

Find all connection schedules
adfind -b "cn=Configuration,dc=qraps,dc=com,dc=au" -f "objectcategory=ntdsConnection" cn Schedule -csv

Software Information for each server
for /f %i in (Output from ‘Domain Controllers’) do psinfo \\%i &filever \\%i\admin$\explorer.exe \\%i\admin$\system32\vbscript.dll\\%i\admin$\system32\kernel32.dll \\%i\admin$\system32\wbem\winmgmt.exe\\%i\admin$\system32\oleaut32.dll

Check Terminal Services Delete Temp on Exit flag
For /f %i in (Output from ‘Domain Controllers’) do Reg query"\\%i\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TerminalServer" /v DeleteTempDirsOnExit
or each XP workstation, query the current site and what Group Policy info
@dsquery * domainroot -filter"(&(objectCategory=Computer)(operatingSystem=Windows XPProfessional))" -limit 0 -attr cn > Workstations.txt & @For /f%i in (Workstations.txt) do @ping %i -n 1 >NUL & @if ErrorLevel0 If NOT ErrorLevel 1 @Echo %i & for /f "tokens=3" %k in (‘"regquery "\\%i\hklm\software\microsoft\windows\currentversion\grouppolicy\history" /v DCName | Find /i "DCName""’) do @for /f %m in(‘"nltest /server:%i /dsgetsite | find /i /v "completedsuccessfully""’) do @echo %i,%k,%m

Information on existing GPOs
dsquery * "CN=Policies,CN=System,domainRoot" -filter"(objectCategory=groupPolicyContainer)" -attr displayName cnwhenCreated gPCFileSysPath

Copy all Group Policy .pol files
for /f "tokens=1-8 delims=\" %i in (‘dir /b /s\\%userdnsdomain%\sysvol\%userdnsdomain%\policies\*.pol’) do @echo copy\\%i\%j\%k\%l\%m\%n\%o %m_%n.pol

Domain Controller Netlogon entries
for /f %i in (‘dsquery server /o rdn’) do echo %i & reg query\\%i\hklm\system\currentcontrolset\services\netlogon\parameters

WINS Statistics
for /f "tokens=1,2 delims=," %i in (WINSServers.txt) do netsh wins server \\%i show statistics

WINS Record counts per server
for /f "tokens=1,2 delims=," %i in (WINSServers.txt) do netsh wins server \\%i show reccount %i

WINS Server Information
for /f "tokens=2 delims=," %i in (WINSServers.txt) do netsh wins server \\%i show info

WINS Server Dump
for /f "tokens=2 delims=," %i in (WINSServers.txt) do netsh wins server \\%i dump

WINS Static Records per Server
netsh wins server \\LocalWINSServer show database servers={} rectype=1

Find policy display name given the GUID
dsquery * "CN=Policies,CN=System,DC=domainRoot" -filter (objectCategory=groupPolicyContainer) -attr Name displayName

Find empty groups
dsquery * -filter "&(objectCategory=group)(!member=*)" -limit 0-attr whenCreated whenChanged groupType sAMAccountNamedistinguishedName memberOf

Find remote NIC bandwidth
wmic /node:%server% path Win32_PerfRawData_Tcpip_NetworkInterface GET Name,CurrentBandwidth

Find remote free physical memory
wmic /node:%Computer% path Win32_OperatingSystem GET FreePhysicalMemory

Find remote system information
SystemInfo /s %Computer%

Disk statistics, including the number of files on the filesystem
chkdsk /i /c

Query IIS web sites
iisweb /s %Server% /query "Default Web Site"

Check port state and connectivity
portqry -n %server% -e %endpoint% -v

Forest/Domain Functional Levels
ldifde -d cn=partitions,cn=configuration,dc=%domain% -r"(|(systemFlags=3)(systemFlags=-2147483648))" -lmsds-behavior-version,dnsroot,ntmixeddomain,NetBIOSName -p subtree -fcon

Forest/Domain Functional Levels
dsquery * cn=partitions,cn=configuration,dc=%domain% -filter"(|(systemFlags=3)(systemFlags=-2147483648))" -attrmsDS-Behavior-Version
Name dnsroot ntmixeddomain NetBIOSName

Find the parent of a process
wmic path Win32_Process WHERE Name=’notepad.exe’ GET Name,ParentProcessId

Lookup SRV records from DNS
nslookup -type=srv _ldap._tcp.dc._msdcs.{domainRoot}

Find when the AD was installed
dsquery * cn=configuration,DC=forestRootDomain -attr whencreated -scope base

Enumerate the trusts from the specified domain
dsquery * "CN=System,DC=domainRoot" -filter "(objectClass=trustedDomain)" -attr trustPartner flatName

Find a DC for each trusted domain
for /f "skip=1" %i in (‘"dsquery * CN=System,DC=domainRoot -filter(objectClass=trustedDomain) -attr trustPartner"’) do nltest /dsgetdc:%i

Check the notification packages installed on all DCs
for /f %i in (‘dsquery server /o rdn’) do @for /f "tokens=4" %m in(‘"reg query\\%i\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa /v"Notification Packages" | find /i "Notification""’) do @echo %i,%m

List ACLs in SDDL format
setacl -on %filepath% -ot file -actn list -lst f:sddl

Find out if a user account is currently enabled or disabled
dsquery user DC=%userdnsdomain:.=,DC=% -name %username% | dsget user -disabled -dn

Find servers in the domain
dsquery * domainroot -filter "(&(objectCategory=Computer)(objectClass=Computer)(operatingSystem=*Server*))" -limit 0

Open DS query window
rundll32 dsquery,OpenQueryWindow

ULS Logs and the ULSViewer

u might have stumbled across this blog entry when looking for information on the ULS. If that is the case, while I will not go into great detail on the ULS I can at least tell you that it stands for stands for Unified Logging Service and is a corner stone of SharePoint troubleshooting and it is the first place I recommend looking at to start tracking down the details of any errors you might be encountering. If you are looking for a decent article on the ULS I’d recommend checking out the general MSDN article that gives a general overview.

Now, assuming that you have at least a basic understanding of the ULS and where the files can be found (default is the “SharePoint HIVE”\Logs folder). If you open one of the files up, I am willing to bet that you would find yourself wondering how on earth you can make heads or tails of the information stored in the file and if you have a large farm, how you can pull it all together so you can track down any issues quickly and more efficiently. Well you are in luck as one of the better tools out there is free, full of features, and rather easy to use. This tool is called the ULSViewer and can be downloaded from here or here.

ULSViewer can be used in different modes. The log can be read from log files, real time ULS log, from multiple servers, or even from the clipboard. Here’s some examples:

On a machine running SharePoint 2010, run ULS Viewer. Click File, Open From, then choose ULS (This could also be done by simply press Ctrl+U).


Immediately the logs will be shown in real-time. From here you can do things like filter by message level by click the icons in the of the tool bar


You can ask set filters based on what you are looking for (error message, correlation id, etc). You can do this by clicking on the “filter” icon in the tool bar and then defining 1 or more filters.


Note: One of the great things you can also do is save filters and reuse them. I find that I have a number of filters that I use over and over and this helps save a lot of time!

Another feature that I find really handy is the “Toggle Correlation Tree” button.


clip_image006 When you click on this it opens up a side panel that can show you a list of all of the correlation ids and when you click on one of those nodes you immediately see the main area filters to show only the log entries related to that single correlation id.

The reason why this is so useful is because in SharePoint we use correlation ids to trace a series of events that occurred at once (like a transaction).

For example if you look at the screenshot below you’ll see that I selected the correlation id ‘ce44ed9c-e3b3-c0ad-3409-5e8c8d8d317f’ and this one appears to be related to a UserProfileImport Sync job.


If you’re running this on a development machine or are trying to track down an error that doesn’t happen regularly another good feature is the notifications. You can enable notification by level in side of ULS Viewer (by default it will pop up notification for Critical message). For example in this screenshot, when Health Analyzer checked my machine for a security rule, it wrote a critical message into the log. With ULS Viewer, you can quickly identify the location of the message. If there’s an exception, you can also check the detail of that.


Another great feature is the ability to open up multiple ULS logs from different servers. So if you have a 4 or 5 server farm, you could either review each log individually or you could open them up as a “FARM” and let ULSView take over the complicated work of combining the log files into a single view. You can do this either from the tool bar by clicking on the “farm” icon or by going to File -> Open From -> Farm (Ctrl+ R)

Farm Icon

File -> Open From


Which then opens this dialog


From here you can add all of your servers (NetBios, FQDN, or IP addresses work just fine) and then specify a share that is available on ALL of the servers list.

Tip: The SAME share must be available on all servers for this to work. I normally create a standard share on all of my SharePoint servers called “UlsLogs” and grant read only access to the development and operations teams.

Also another useful feature is that once you have configure ULSView for your environment (include what servers/files are being monitored), you can save everything to a “workspace”. This workspace can be shared with others and opened at any time. This provides a very quick way to start viewing a farm.


Tip: I usually create one workspace per environment and share what with the development and operations team.

Project Server and Synchronizing Users to Project Sites

Original post found here

This blog post looks at some slight behavior differences between Project Server 2010 and Project Server 2013 regarding user synchronization to project sites.  One key part of this change should be taken into account when migrating – as there is one 2010 setting that no longer has UI to change it – and if it is disabled before migration it cannot be turned on again in 2013.  I’ll get into details of that setting and a workaround later, but first I will set the scene for how the settings and behavior have evolved. 

In Project Server 2010 we had a checkbox in Server Settings, Project Site Provisioning Settings for Project Site Permissions – labeled “Check to automatically synchronize Project Web App users with Project Sites when they are created, when project managers publish projects, and when user permissions change in Project Server. When the check box is cleared, Project Server users are never synchronized with Project Sites.”:


In my example it is unchecked – this is reflected in the published database in the MSP_WEB_ADMIN table in the WADMIN_AUTO_ADD_USER_TO_SUBWEB column – which has 0 when unchecked and 1 when checked.


If I create a new project and add some resources and then publish – I see just the following jobs in the queue and I don’t see any permissions set for the resources in my plan.

Project Save from Project Professional  
Start Workflow Success
Project Publish Notifications
Project Publish Success
Reporting (Project Publish)
Project Site Create
Reporting (Project Sync)
Reporting (Enterprise Project Type and Workflow Information Sync)

If I go to Server Settings, Project Sites and select the project, then click Synchronize in the header:


then I see a couple of queue jobs executed:

Project Site Membership Synchronization
Reporting (Project Sync)

However, I still do not see my expected users added to my site.  Only when I check the checkbox in the first screenshot, and then click Synchronize on the Project Sites page do I see my users get added.  So this checkbox controls the addition of users to my subweb.

There are some other settings in 2010 that had no UI, but could be set programmatically (or by editing the database and were documented in the article and the table was the same MSP_WEB_ADMIN, but this time the column is WADMIN_USER_SYNC_SETTING:


As you can see, mine is set to 0, which means all synchronizations are enabled.  If I change this to 2, this still has no effect on the site synchronization as long as the checkbox is checked.  Sync happens both on site creation and also using the Synchronize button.

Now lets jump forward to 2013.  The dialog in my first screenshot has no equivalent in 2013, and in a new installation the database setting for WADMIN_AUTO_ADD_USER_TO_SUBWEB  is defaulted to 1.  The WADMIN_USER_SYNC_SETTING now has some UI – under Server Settings, Project Permission Sync Settings.  I should add that this only appears when you are using Project Server Permissions mode.  The dialog looks like this:  , and if you are interested in the behind the scenes activity in the pub.MSP_WEB_ADMIN table the values for :


If you are interested in the behind the scenes activity in the pub.MSP_WEB_ADMIN table the values for WADMIN_USER_SYNC_SETTING follow the numbers documented at like so:

Enabled                            Value=0.       Enable all synchronizations.

DisablePWA                     Value=1.       Disable synchronization with Project Web App.

DisablePWS                     Value=2.       Disable synchronization with project sites.

DisableEmailSync             Value=3.       Disable email synchronization.

DisableAll                         Value=4.       Disable all synchronizations.

DisableVisbilityProjects    Value=8.       Disable Visibility projects synchronization only.

DisableEverything            Value = 255. Disable everything.

Unchecking Enable Project Site Sync will give me a value of 10 in the database – as it disables project site sync and sync with SharePoint Task List Project (or visibility projects as they are sometimes called).

With these settings, which are equivalent to the ones described in the final 2010 test above  (DB value was 2 rather than 10 as visibility projects didn’t exist),  if I create a new project and publish, and/or if I click Synchronize on the Connected SharePoint Sites page I DO NOT see any synchronize queue jobs and NO users are added to my site.  In 2013 there is no longer a single click option to synchronize sites if I have used the new UI in front of the WADMIN_USER_SYNC_SETTING values to turn off site sync.

The other gotcha, and the piece that got me looking deeper into this topic in the first place is the issue I alluded to in the intro.  What if I am using 2010 and have that box unchecked – then migrate to 2013?  In this case it can leave you confused as to why your users aren’t able to access their sites after you create a project.  The behavior you will see is that on initial publish of a project, assuming you create a site, then even if you have ‘Enable Project Site Sync’ enabled you will still not see your users added – and neither will you see the expected additional ‘Project Web App Synchronized’ groups – you will just see the default members, Owners and Visitors if you go to Site Settings, Site Permissions:


If you click on the Synchronize option you will see things put right – and the new groups will get added and your users added.  So we still take notice of the old DB setting which carried over from migration – but only on the project publish.


This last piece is certainly a bug – not sure at this point how it will be addressed, but we will be updating our upgrade documents to suggest checking that box before migration.  If you have migrated from 2010 (or earlier!) and are not seeing permissions on sites set as expected when you publish a plan then take a look at the database (change ProjectWebApp to the name of your database),


should return a 1.  If it shows a zero then you could run

Update [ProjectWebApp_PPM].[pub].[MSP_WEB_ADMIN]

This will show (1 rows(s) affected) as it resets the value.

We are reviewing this behavior change – so I will update if we do make any changes here.

For Project Online this last piece can never be an issue – as it will always be a 1 – and Project Online now has new defaults for the other Project Permissions Sync Settings – so by default we don’t sync anything.  And like 2013, if you have this sync turned off then Synchronize in Connected SharePoint Sites does nothing.

Setting Up Neo4j 2.0 on an Ubuntu Server

Authored by Steven Hall

Neo4j 2.0 is an awesome release of Neo Technology's great graph database.  There are some significant new features and some changes to the data model that, I think, make it more accessible.  You can install it locally to play around and do some testing, but I wanted to create a remote server that I could use as a back-end for data visualization projects.  Below are some notes on getting Neo4j installed on Ubuntu 12.04. 

There are some real gotchas that took some time to figure out, but if you follow this step-by-step procedure you should have the browser application bundled with Neo4j up and running in less than 15 minutes.

I should note that the Neo4j website has instructions for setting up on debian based systems, but those instructions, which are very helpful, are incomplete and in some cases just don't work for Ubuntu 12.04 (at least at the time I am writing this post).

Start from Fresh Ubuntu 12.04 Install

Neo4j is a Java application and in order to run the 2.0 version of the db server you need to have Java 7 installed before installing Neo4j.  Ubuntu does not officially support Java 7 so this becomes at little bit of a headache.  To install it using apt-get you need to add a repository and, incredibly, the command for adding repositories was unintentionally left out the latest versions of Ubuntu, so we need to correct that first.

You can add "sudo" (e.g. sudo apt-get update) to the following commands as applicable.  In my case, I installed as the root user on the server.

Install Java 7

Add the "add-apt-repository" command (important):

apt-get update
apt-get install python-software-properties

Install Java 7:

add-apt-repository ppa:webupd8team/java
apt-get update
apt-get install oracle-java7-installer

Install Neo4j:

Note:  this largely the same as Neo4j recommends, but I had to change a few things.

wget -O - | apt-key add -
echo 'deb stable/' > /etc/apt/sources.list.d/neo4j.list
apt-get update
apt-get install neo4j

Start the Server:

/etc/init.d/neo4j-service start

Increasing Max Files

You'll notice when you start the server that you get warning saying:

WARNING: Max 1024 open files allowed, minimum of 40 000 recommended.

Let's correct that.  The instructions for handling this on the neo4j website did not work for me without a little modification.  Here's what to do:

1. Edit /etc/security/limits.conf and add these two lines:
root   soft     nofile  40000
root   hard    nofile  40000

The neo4j recommends "neo4j" in place of "root" here.  That does not work.

2. Edit /etc/pam.d/su and uncomment or add the following line:
session    required

A restart is required for the settings to take effect.

Optionally Allow External Connections

If you want to be able to open the browser app and interact with the graph db on the remote server you need to allow remote connections.  Note that if you allow any IP address to connect then anyone can access your database, but if you just want to play around with the browser app this is what you do:

Edit /etc/neo4j/ and uncomment the following line:


That will allow connections from any IP address, but you can also specify your current IP to limit to just that one.  That will make it a little bit safer, but if your IP changes you need to update the file accordingly.

So now just restart the database server and open the browser application in your web browser by going to:



Removing All Data from Neo4j

A couple more quick notes.  If you are playing around with the neo4j database and just want to clear it out and start over again, there are two things you can do:

1. Run a cypher query like this:

match n
with n
optional match n-[r]-()
delete r,n

This will remove all the nodes and relations in the db. However, a lot of meta-data remains and, in my experience, if have a lot of data in the db it will fail or take a long time to run (or both).

2. Recreate the Data Directory

If you really want to get the job done, it's better to wipe out the entire data directory and make a new one.  The default directory is set in the /etc/neo4j/ file to data/graph.db.  On Ubuntu this directory will be located at :


To wipe out the data the process would be:

/etc/init.d/neo4j-service stop         //Stop the Server
cd /var/lib/neo4j                           // Change to directory
rm -rf data                                    // Remove data/
mkdir data                                  // Make a new data/
chown neo4j data                     // Make sure neo4j can write to it
/etc/init.d/neo4j-service start    // Restart - Neo4j will make new graph.db etc

Hope that helps someone out there.


English Pronunciation -- a very cool poem

If you can pronounce correctly every word in this poem, you will be speaking English better than 90% of the native English speakers in the world. After trying the verses, a Frenchman said he’d prefer six months of hard labour to reading six lines aloud.

Dearest creature in creation,
Study English pronunciation.
I will teach you in my verse
Sounds like corpse, corps, horse, and worse.
I will keep you, Suzy, busy,
Make your head with heat grow dizzy.
Tear in eye, your dress will tear.
So shall I! Oh hear my prayer.
Just compare heart, beard, and heard,
Dies and diet, lord and word,
Sword and sward, retain and Britain.
(Mind the latter, how it’s written.)
Now I surely will not plague you
With such words as plaque and ague.
But be careful how you speak:
Say break and steak, but bleak and streak;
Cloven, oven, how and low,
Script, receipt, show, poem, and toe.
Hear me say, devoid of trickery,
Daughter, laughter, and Terpsichore,
Typhoid, measles, topsails, aisles,
Exiles, similes, and reviles;
Scholar, vicar, and cigar,
Solar, mica, war and far;
One, anemone, Balmoral,
Kitchen, lichen, laundry, laurel;
Gertrude, German, wind and mind,
Scene, Melpomene, mankind.
Billet does not rhyme with ballet,
Bouquet, wallet, mallet, chalet.
Blood and flood are not like food,
Nor is mould like should and would.
Viscous, viscount, load and broad,
Toward, to forward, to reward.
And your pronunciation’s OK
When you correctly say croquet,
Rounded, wounded, grieve and sieve,
Friend and fiend, alive and live.
Ivy, privy, famous; clamour
And enamour rhyme with hammer.
River, rival, tomb, bomb, comb,
Doll and roll and some and home.
Stranger does not rhyme with anger,
Neither does devour with clangour.
Souls but foul, haunt but aunt,
Font, front, wont, want, grand, and grant,
Shoes, goes, does. Now first say finger,
And then singer, ginger, linger,
Real, zeal, mauve, gauze, gouge and gauge,
Marriage, foliage, mirage, and age.
Query does not rhyme with very,
Nor does fury sound like bury.
Dost, lost, post and doth, cloth, loth.
Job, nob, bosom, transom, oath.
Though the differences seem little,
We say actual but victual.
Refer does not rhyme with deafer.
Foeffer does, and zephyr, heifer.
Mint, pint, senate and sedate;
Dull, bull, and George ate late.
Scenic, Arabic, Pacific,
Science, conscience, scientific.
Liberty, library, heave and heaven,
Rachel, ache, moustache, eleven.
We say hallowed, but allowed,
People, leopard, towed, but vowed.
Mark the differences, moreover,
Between mover, cover, clover;
Leeches, breeches, wise, precise,
Chalice, but police and lice;
Camel, constable, unstable,
Principle, disciple, label.
Petal, panel, and canal,
Wait, surprise, plait, promise, pal.
Worm and storm, chaise, chaos, chair,
Senator, spectator, mayor.
Tour, but our and succour, four.
Gas, alas, and Arkansas.
Sea, idea, Korea, area,
Psalm, Maria, but malaria.
Youth, south, southern, cleanse and clean.
Doctrine, turpentine, marine.
Compare alien with Italian,
Dandelion and battalion.
Sally with ally, yea, ye,
Eye, I, ay, aye, whey, and key.
Say aver, but ever, fever,
Neither, leisure, skein, deceiver.
Heron, granary, canary.
Crevice and device and aerie.
Face, but preface, not efface.
Phlegm, phlegmatic, ass, glass, bass.
Large, but target, gin, give, verging,
Ought, out, joust and scour, scourging.
Ear, but earn and wear and tear
Do not rhyme with here but ere.
Seven is right, but so is even,
Hyphen, roughen, nephew Stephen,
Monkey, donkey, Turk and jerk,
Ask, grasp, wasp, and cork and work.
Pronunciation (think of Psyche!)
Is a paling stout and spikey?
Won’t it make you lose your wits,
Writing groats and saying grits?
It’s a dark abyss or tunnel:
Strewn with stones, stowed, solace, gunwale,
Islington and Isle of Wight,
Housewife, verdict and indict.
Finally, which rhymes with enough,
Though, through, plough, or dough, or cough?
Hiccough has the sound of cup.
My advice is to give up!!!

English Pronunciation by G. Nolst Trenité