Tuesday, August 21, 2012

Enabling Powershell Remoting

I manage a bunch of SharePoint farms and have finally gotten around to setting up Powershell Remoting to streamline some of my maintenance tasks.

Following the post Enable and Use Remote Commands in Windows PowerShell, I run the following on my remote servers:
Enable-PSRemoting -force

From my client machine, I tried the following:
Enter-PSSession -Computername $computername -Credential $credential

This resulted in the following error:

Enter-PSSession : Connecting to remote server failed with the following error message : WinRM cannot process the request. The following error occured while using Kerberos authentication: The network path was not found.
 Possible causes are:
  -The user name or password specified are invalid.
  -Kerberos is used when no authentication method and no user name are specified.
  -Kerberos accepts domain user names, but not local user names.
  -The Service Principal Name (SPN) for the remote computer name and port does not exist.
  -The client and remote computers are in different domains and there is no trust between the two domains.
 After checking for the above issues, try the following:
  -Check the Event Viewer for events related to authentication.
  -Change the authentication method; add the destination computer to the WinRM TrustedHosts configuration setting or use HTTPS transport.
 Note that computers in the TrustedHosts list might not be authenticated.
   -For more information about WinRM configuration, run the following command: winrm help config. For more information,
 see the about_Remote_Troubleshooting Help topic.

I verified that my firewall was allowing the WinRM ports.

I set my trusted hosts on my remote servers using:
winrm s winrm/config/client '@{TrustedHosts="MyComputerName"}'

I then came across this post on how to enable Remote PSSession over SSL. I have a wildcard certificate for my domain. Modifying the script ever so slightly, I ran the following to enable HTTPS and disable HTTP transport
winrm create winrm/config/listener?Address=*+Transport=HTTPS `@`{Hostname=`"MyCertificateIssuedTo`"`; CertificateThumbprint=`"MyCertificateThumbprint`"`}
netsh advfirewall firewall add rule name="Windows Remote Management (HTTPS-In)" protocol=TCP dir=in localport=5986 action=allow
winrm set winrm/config/Listener?Address=*+Transport=HTTP `@`{Enabled=`"false`"`}
netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=no

Now I get the following error:

Enter-PSSession : Connecting to remote server failed with the following error message : The server certificate on the destination computer (MyComputerName) has the following errors:
The SSL certificate contains a common name (CN) that does not match the hostname. For more information, see the about_Remote_Troubleshooting Help topic.

Aha! Progress! Now looking at the Securing WinRM thread, I try the -SkipCACheck and -SkipCNCheck Session Options as described. Now I get the following error:

Enter-PSSession : Cannot bind parameter 'SessionOption'. Cannot convert the "Microsoft.WSMan.Management.SessionOption" value of type "Microsoft.WSMan.Management.SessionOption" to type "System.Management.Automation.Remoting.PSSessionOption".

It looks like some types have changed since that thread was posted. So, I used the following instead

Enter-PSSession -ComputerName $computername -Credential $credential -UseSSL -SessionOption (New-PSSessionOption -SkipCACheck -SkipCNCheck)


Monday, August 20, 2012

Locating unghosted pages

I recently came across a page that was giving me this error:
The control type '...' is not allowed on this page. The type is not registered as safe.

The obvious solution is to add a <SafeControl> tag to the web.config, but checking with my developer, he said it was not necessary and he does not have that declaration on his test server.

This led me to hypothesize that a custom branding we had was causing the problem to which my developer corroborated that unghosted master pages will cause problems.

So how to locate the unghosted pages? This led me to the following post: Ghosts in the Machine? However, this is for SharePoint 2007 so taking a leap of faith, I modified the SQL script provided and came up with this:

  FROM [WSS_Content].[dbo].[AllDocs]
  where ([AllDocs].[Type] = 0)
  AND ([AllDocs].SetupPath IS NOT NULL)
  AND ([AllDocs].DocFlags & 64 = 64) 

Checking the reference for the AllDocs Table this query seemed to make sense.