Wednesday, October 2, 2013

The server is unavailable and could not be accessed. The server is probably disconnected from the network

All of a sudden my FAST search crawler is returning the following error on every item:
The server is unavailable and could not be accessed. The server is probably disconnected from the network

I already had DisableLoopbackCheck enabled so that wasn't it.
In any case, I removed the DisableLoopbackCheck and decided to try BackConnectionHostNames instead (ie: the safer method). This also didn't help
I tried adding in DisableStrictNameChecking. This also didn't help.
Hours of searching, I was about to give up, then I thought I'd check the hosts file. At that point, I remembered that I added an entry there when I had previously done some maintenance on that server. After I removed that errant entry, my crawler now works.

Tuesday, June 18, 2013

%systemdrive% in Powershell

I was just trying to write a script to manage IIS logs. I was able to get the log directory, but it comes back as  %SystemDrive%\inetpub\logs\LogFiles

Reading between the lines from a couple of posts, I found that I can use $env:SystemDrive in place of %SystemDrive%

So I can do something like this:
Import-Module WebAdministration
$website = Get-Website | Where-Object {$ -eq 'SharePoint - 443'}
$logfileDirectory = $ -replace '%SystemDrive%', $env:SystemDrive

Wednesday, June 5, 2013

0x80070002 when adding web part using Powershell

I was adding a webpart using this powershell:
$webpart = New-Object Microsoft.SharePoint.WebPartPages.SilverlightWebPart
$wpm = $web.GetLimitedWebPartManager($page.Uri.OriginalString, "Shared")
$wpm.AddWebPart($webpart, 'Header', 0)

... and got this error:

Exception calling "AddWebPart" with "3" argument(s): "<nativehr>0x80070002</nativehr><nativestack></nativestack>"
At line:1 char:16
+ $wpm.AddWebPart <<<< ($webpart, 'Header', 0)
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

It turns out that my $page was the wrong one which was not checked out nor editable at the time.

Listing a page's web part zones

I have been trying to figure out a way to list all of a page's web part zones. There is not much documentation out there on this. Here's what I have been able to figure out. It is for a publishing web, but the procedure should be pretty much the same.

$web = Get-SPWeb $myweburl
$pWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($web)
$layout = $pWeb.GetAvailablePageLayouts() | Where-Object {$_.Title -eq $mylayouttitle}

And to list the webparts on a page:
$wpm = $web.GetLimitedWebPartManager($pageurl, 'Shared'
$wpm.WebParts | Format-Table -AutoSize WebBrowsableObject, ZoneId, ZoneIndex

There's also a post Determine which webpartzones are on a webpartpage that uses reflection to get at a private member however I have not gotten it to work.

Wednesday, April 17, 2013

Could not load the current My Site settings

I have a new SP2013 installation and going into the Setup My Sites, I get the error:
Could not load the current My Site settings

Doing a quick search, I came across this:

It turned out that my Search Service Application was broken as described here:

Unable to retrieve topology component health states. This may be because the admin component is not up and running

I just installed SP2013 RTM on Win2k8R2 SP1 and SQL2012 Enterprise on a separate Win2k8R2 SP1 server. I used Powershell to provision my Search as follows:

$ssi = Get-SPServiceInstance | Where-Object {$_.TypeName -eq 'SharePoint Server Search'}
Start-SPServiceInstance $ssi
WaitForServiceInstance $ssi.TypeName
$searchAdminAppPool = Get-SPServiceApplicationPool -Identity $AppPoolSearchAdmin
$searchQueryAppPool = Get-SPServiceApplicationPool -Identity $AppPoolSearchQuery
New-SPEnterpriseSearchServiceApplication -Name 'Search Service Application' -ApplicationPool $searchQueryAppPool -AdminApplicationPool $searchAdminAppPool
New-SPEnterpriseSearchServiceApplicationProxy -Name 'Search Service Application' -SearchApplication (Get-SPEnterpriseSearchServiceApplication 'Search Service Application')
Set-SPEnterpriseSearchService -ServiceAccount $searchServiceAccount -ServicePassword (ConvertTo-SecureString -AsPlainText -Force $password)

When I go into manage my Search Service Application, I get the following error:
Unable to retrieve topology component health states. This may be because the admin component is not up and running

Figuring that I may have been missing some steps in my Powershell script, I tried unprovisioning my Search Service Application and reprovisioning using Central Administration. Still the same problem. Time to do some searches. Here is what I found.

After doing a lot of reading and considering the various CUs, I went back to my servers to try some of the suggested solutions. Lo and behold, search is working now. The only things I can infer from this is:

  1. Central Administration is doing something to provision Search that is missing from my Powershell script
  2. Some process took its time to execute
  3. Possibly some random factors like memory, etc.

As much as I would like to know the real answer, it is working now, time to move onto next problem.

Friday, April 5, 2013

Managing assemblies with Powershell

A simple way to access assemblies and see what's in them. Still a work in progress. I hope to add more tricks to this post soon.

Load in the assembly
$assembly = [Reflection.Assembly]::LoadFile($assemblyPath)
$assembly = [Reflection.Assembly]::Load($assemblyName)

Get details on a type defined in the assembly
$type = $assembly.DefinedTypes | Where-Object {$_.Name -eq $typeName}
$type.DeclaredConstructors | ForEach-Object {$_.ToString()}
$type.DeclaredMethods | ForEach-Object {$_.ToString()}

To load the assembly for use
Add-Type -Path $assemblyPath #if assembly in file
Add-Type -AssemblyName $assemblyName #if assembly in GAC
For some reason $assemblyName must be the full name contrary to the documentation in Add-Type

Get all assemblies in current AppDomain
[AppDomain]::CurrentDomain.GetAssemblies() | Select-Object FullName | Sort-Object FullName

System.Reflection.Assembly class
Add-Type cmdlet
AppDomain class

Windows Azure storage through Powershell

This is just a first stab at manipulating Windows Azure Storage via Powershell.

Get Microsoft.WindowsAzure.Storage.dll using NuGet 
  1. Navigate to this by first going to the Windows Azure Downloads site.
  2. Select .NET. 
  3. Select Client libraries under Resources.
  4. Instructions on how to download Windows Azure Storage are found here. 
Here is the code I'm using to download files from blob storage

Param (
    [Parameter(Mandatory=$true)] [String] $StorageAccountName,
    [Parameter(Mandatory=$true)] [String] $AccessKey,
    [Parameter(Mandatory=$true)] [String] $BlobFilename,
    [Parameter(Mandatory=$true)] [String] $LocalFilename,
    [String] $StorageAccountEndpoint = "http://$"

Add-Type -Path '.\Microsoft.WindowsAzure.Storage.dll'

$BlobFilename = $BlobFilename.Replace('%20', ' ').Trim('/')
$storageCredentials = New-Object Microsoft.WindowsAzure.Storage.Auth.StorageCredentials($StorageAccountName, $AccessKey)
$blobClient = New-Object Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient($StorageAccountEndpoint, $storageCredentials)
$blob = $blobClient.GetBlobReferenceFromServer($BlobFilename)
$stream = New-Object System.IO.FileStream($LocalFilename, [System.IO.FileMode]::Create)

Monday, March 25, 2013

PowerShellPack TaskScheduler Remove-Task.ps1 Method invocation failed because [System.String] doesn't contain a method named 'DeleteTask'

I am using the Remove-Task cmdlet in the TaskScheduler module of PowerShellPack to manage some Task Scheduler tasks and getting this weird error:
Method invocation failed because [System.String] doesn't contain a method named 'DeleteTask'

So, I took a look at the code found at ...\Documents\WindowsPowerShell\Modules\TaskScheduler\Remove-Task.ps1 and found an error. The version I have looks like this at lines 53-58:

        switch ($psCmdlet.ParameterSetName) {
            Task { 
                $scheduler = Connect-ToTaskScheduler -ComputerName $ComputerName -Credential $Credential
                $folder =$scheduler.GetFolder("")
                $folder.DeleteTask($task.Path, 0)

The problem is that there is a [String[]] $Folder = "" declaration earlier on in the code.

I changed it to the following and it looks like it works:
        switch ($psCmdlet.ParameterSetName) {
            Task { 
                $scheduler = Connect-ToTaskScheduler -ComputerName $ComputerName -Credential $Credential
                $taskfolder =$scheduler.GetFolder("")
                $taskfolder.DeleteTask($task.Path, 0)

Coincidentally, the Get-ScheduledTask.ps1 cmdlet uses the same idea so the original author must have just missed this. The module looks like it hasn't been updated for quite some time.

Thursday, March 21, 2013

Bulk reset of passwords

Recently, I had to reset a whole bunch of passwords. This can be easily done via PowerShell.

$Excludes = @('user1', 'user2')
$Password = ConvertTo-SecureString -AsPlainText -Force 'mypassword'
$SearchBase = "OU=Some OU,DC=Some DC,DC=Some DC"

Import-Module ActiveDirectory

Get-ADUser -Filter * -SearchBase $SearchBase | Where-Object {$Excludes -notcontains $_.SamAccountName} | Set-ADAccountPassword -NewPassword $Password

Then to check what was done:

Get-ADUser -Filter * -Properties SamAccountName, PasswordLastSet | Select-Object SamAccountName, PasswordLastSet | Sort-Object PasswordLastSet -Descending

Extracting data from SQL Azure using Powershell

I have a SQL Website that is logging some debug output to a SQL Azure DB Linked Resource. In order to do some quick troubleshooting, I tried using the Manage interface in Azure, however it is lacking a way to export the data. I could manually copy and paste out database rows and columns, but that is a pain. I don't have SQL 2013 Management Studio and just want a lightweight way for me to access my databases.

I ended up doing this with Powershell:


$connectionString = "Data Source=$datasource;Initial Catalog=$database;User ID=$userid;Password=$password;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;"
$SqlCmd=New-Object System.Data.SqlClient.SqlCommand($CommandText)
$SqlCmd.Connection=New-Object System.Data.SqlClient.SqlConnection($ConnectionString)

$SqlAdapter=New-Object System.Data.SqlClient.SqlDataAdapter($SqlCmd)
$DataSet=New-Object System.Data.DataSet
I can then get at the data through $DataSet.

I can also get the connection string though the Windows Azure console and go to SQL Databases, select my database, select "View SQL Database connection strings for ADO .Net, ODBC, PHP, and JDBC", copy the ADO.NET connection string, and replace "Server" with "Data Source", "Database" with "Initial Catalog", and "{your_password_here}" with my password.

Error: The configuration section 'microsoft.applicationServer' cannot be read because it is missing a section declaration

Recently, I have been trying to install some code on a brand new server running Windows 2008 R2 SP1 and .NET 4.0. However, I kept running into the following error: Error: The configuration section 'microsoft.applicationServer' cannot be read because it is missing a section declaration

There are many resources out there talking about adding various things. It turns out that what I was missing was AppFabric.

Ouch! I wasted a lot of time on that one.

Thursday, January 24, 2013

Enabling incoming email on SharePoint 2013

I am running SharePoint 2013 RTM on one of my demo servers and want to enable incoming email. The configuration is exactly the same as in SharePoint 2010:
Setup your SMTP server to receive email
Set "Enable sites on this server to receive e-mail" to Yes
Verify firewall settings to allow connections to port 25

However, after checking all this, my incoming email was still not making it into my lists. I can see the incoming email message sitting in the C:\inetpub\mailroot\Drop folder and it is not being processed.

By chance, I decided to set "Enable sites on this server to receive e-mail" to No, save and then back to Yes. Then miraculously, the incoming email is now being processed. I have now seen this exact behaviour several times with my SharePoint 2013 instances.

Monday, January 7, 2013

SharePoint 2013 About Me page timing out

For some reason, all of a sudden, I am no longer able to access my "About Me" page (/my/Person.aspx) on one of my SharePoint 2013 demo servers. I can access the "About Me" page for everyone else and everyone else can also access their "About Me" page, but no one can access mine. It seems to spin for a long time and then time out. The only thing in ULS is an aborted thread exception.

Finally, I tried accessing the edit page of my "About Me" using /my/_layouts/15/EditProfile.aspx, hit save without even changing anything and magically, I can see my "About Me" page again.

Very bizarre.

Crawling root web of a site collection

I was recently trying to troubleshoot a search problem with my application. It turned out that there was a list at the root web of a site collection that was not being indexed by search.

$ssa = Get-SPEnterpriseSearchServiceApplication | Where-Object {$_.Name -eq "FAST Search Query Service Application"}
$logViewer = New-Object Microsoft.Office.Server.Search.Administration.LogViewer($ssa)
$urlProperty = [Microsoft.Office.Server.Search.Administration.CrawlLogFilterProperty]::Url
$stringOperator = [Microsoft.Office.Server.Search.Administration.StringFilterOperator]::Contains
$crawlLogFilters = New-Object Microsoft.Office.Server.Search.Administration.CrawlLogFilters
$searchUrl = 'my URL'
$crawlLogFilters.AddFilter($urlProperty, $stringOperator, $searchUrl)
$urls = $logViewer.GetCurrentCrawlLogData($crawlLogFilters, ([ref] $i))

Then I checked with a colleague and it turns out that all I needed to check was Site Actions->Site Settings->Search and offline availability. The "Allow this site to appear in search results" was set to No.