<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>alexst</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/alexst/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/alexst/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 03:22:46 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Creating and configure a SharePoint 2013 Enterprise Search Service Application with a two-tier topology</title>
      <link>https://docs.microsoft.com/archive/blogs/alexst/creating-and-configure-a-sharepoint-2013-enterprise-search-service-application-with-a-two-tier-topology</link>
      <pubDate>Wed, 08 Jan 2014 13:52:00 GMT</pubDate>
      <dc:creator><![CDATA[Alex Strachan]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/alexst/2014/01/08/creating-and-configure-a-sharepoint-2013-enterprise-search-service-application-with-a-two-tier-topology/</guid>
      <description><![CDATA[SharePoint 2013 Enterprise Search is a major feature of SharePoint 2013, however the topology must...]]></description>
      <content:encoded><![CDATA[<p>SharePoint 2013 Enterprise Search is a major feature of SharePoint 2013, however the topology must be set in PowerShell which can present a challenge.&nbsp; To address this, I have written a script that will create the application and its dependencies and create a two-tier search topology.&nbsp;</p>
<p>The tiers are &quot;Search Front End&quot; which servers user queries and store the index and &quot;Search Back End&quot; which crawl and host the administration components.&nbsp; The machinery is in place to add additional tiers if desired, just add in a new variable with server names and replicate a foreach() block in the &quot;#Build and Set the Topology&quot; section and adjust the services that should run on each tier.</p>
<p>The script will prompt for credentials that should be used for the Default Content Access Account.&nbsp; Additionally, the managed account that the Search Service Application pool will run under must be a previously-configured managed account.</p>
<p></p>
<p>#Add SharePoint PowerShell snap-in<br />Add-PSSnapin microsoft.sharepoint.powershell</p>
<p>##### Set Local Variables<br />#Search Application Pool Name<br />$SearchAppPoolName = &quot;SearchServicePool&quot;<br />#Search Application Pool Account, must be a previously registered managed account<br />$SearchAppPoolAccount = &ldquo;CONTOSO\account&rdquo;<br />#Crawl Account Name<br />$CrawlAccount = Get-Credential -Message &quot;Default Content Access Account Credentials&quot;<br />#Search Service Application Name<br />$SearchAppName = &quot;Search Service Application&quot;<br />#Search Service Application Proxy Name<br />$SearchProxy = &quot;$SearchAppName Proxy&quot;<br />#Database Server that hosts the application<br />$DBServer = &quot;SQL\instance&quot;<br />#Root Database Name for Search Service Application<br />$DBName = &quot;SP_Search&quot;<br />#Drive Path where SharePoint should store the Search Index, must already exist.<br />$Indexlocation = &ldquo;I:\Index&rdquo;<br />#Search Front End Server List, separate each server with a comma.<br />$SearchFrontEnds = &quot;Server1&quot;, &quot;Server2&rdquo;<br />#Search Application Servers List<br />$SearchAppSrvs = &quot;Server1&quot;, &quot;Server2&rdquo;<br />#Get Application Pool for Search Administration Service, must already exist.<br />$AdminAppPool = Get-SPServiceApplicationPool -Identity &quot;SearchServicePool&quot;<br />#####</p>
<p>#Create Search Application Pool<br />&quot;Provisioning Search Application Pool...&rdquo; | Write-Host<br />$AppPool = New-SPServiceApplicationPool -Name $SearchAppPoolName -Account $SearchAppPoolAccount</p>
<p>#Start the search service instances on each of the search servers<br />&quot;Starting Search Service Instances...&rdquo; | Write-Host<br />foreach($ServerName in $SearchFrontEnds){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Start-SPEnterpriseSearchServiceInstance -Identity $ServerName<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance -Identity&nbsp;&nbsp;&nbsp;&nbsp; $ServerName<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />foreach($ServerName in $SearchAppSrvs){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Start-SPEnterpriseSearchServiceInstance -Identity $ServerName<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance -Identity&nbsp;&nbsp;&nbsp;&nbsp; $ServerName<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>#Wait for the Services to provision&nbsp;<br />while(Get-SPEnterpriseSearchServiceInstance | ?{$_.status -eq &quot;Provisioning&quot;}){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; start-sleep 2<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />#Confirm that everything provisioned correctly by cycling through the search servers and ensuring that the Search Service Instance is &ldquo;Online&rdquo;<br />foreach($ServerName in $SearchFrontEnds){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!((Get-SPEnterpriseSearchServiceInstance -Identity $ServerName).status -eq &quot;Online&quot;)){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw(&ldquo;The Search Instance on $ServerName failed to provision.&nbsp; Run Get-SPEnterpriseSearchServiceInstance to view the status of all Search Service Instances&rdquo;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />foreach($ServerName in $SearchAppSrvs){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!((Get-SPEnterpriseSearchServiceInstance -Identity $ServerName).status -eq &quot;Online&quot;)){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw(&ldquo;The Search Instance on $ServerName failed to provision.&nbsp; Run Get-SPEnterpriseSearchServiceInstance to view the status of all Search Service Instances&rdquo;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&quot;Search Instances Provisioned`n&rdquo; | Write-Host</p>
<p>#Create Search Service Application and Application Proxy in SharePoint<br />&quot;Provisioning Search Service Application and Proxy...&quot; | Write-Host<br />New-SPEnterpriseSearchServiceApplication -Name $SearchAppName -ApplicationPool $SearchAppPoolName -DatabaseName $DBName -AdminApplicationPool $AdminAppPool<br />Start-Sleep 10<br />#Create Search Service Application and Proxy<br />New-SPEnterpriseSearchServiceApplicationProxy -Partitioned -Name $SearchProxy -SearchApplication $SearchAppName<br />Start-Sleep 10<br />Set-SPEnterpriseSearchServiceApplication -Identity $SearchAppName -DefaultContentAccessAccountName $CrawlAccount.Username -DefaultContentAccessAccountPassword $CrawlAccount.Password<br />$SearchServiceApp = Get-SPEnterpriseSearchServiceApplication -Identity $SearchAppName</p>
<p>##### Build and Set the Topology<br />#Create the Topology Object<br />&quot;Building Search Topology...&rdquo; | Write-Host<br />$newTopology = New-SPEnterpriseSearchTopology -SearchApplication $SearchServiceApp</p>
<p>#Define Search Front End Topology<br />foreach($ServerName in $SearchFrontEnds){<br />&nbsp;&nbsp;&nbsp;&nbsp; $ServerInstance = Get-SPEnterpriseSearchServiceInstance -Identity $ServerName<br />&nbsp;&nbsp;&nbsp;&nbsp; New-SPEnterpriseSearchQueryProcessingComponent -SearchTopology $newTopology -SearchServiceInstance $ServerInstance<br />&nbsp;&nbsp;&nbsp;&nbsp; New-SPEnterpriseSearchIndexComponent -SearchTopology $newTopology -SearchServiceInstance $ServerInstance -RootDirectory $IndexLocation -IndexPartition 0<br />&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>#Define Search Application Server Topology<br />foreach($ServerName in $SearchAppSrvs){<br />&nbsp;&nbsp;&nbsp;&nbsp; $ServerInstance = Get-SPEnterpriseSearchServiceInstance -Identity $ServerName<br />&nbsp;&nbsp;&nbsp;&nbsp; New-SPEnterpriseSearchAdminComponent -SearchTopology $newTopology -SearchServiceInstance $ServerInstance<br />&nbsp;&nbsp;&nbsp;&nbsp; New-SPEnterpriseSearchCrawlComponent -SearchTopology $newTopology -SearchServiceInstance $ServerInstance<br />&nbsp;&nbsp;&nbsp;&nbsp; New-SPEnterpriseSearchContentProcessingComponent -SearchTopology $newTopology -SearchServiceInstance $ServerInstance<br />&nbsp;&nbsp;&nbsp;&nbsp; New-SPEnterpriseSearchAnalyticsProcessingComponent -SearchTopology $newTopology -SearchServiceInstance $ServerInstance<br />&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>#Set the Topology<br />&quot;Setting Topology...&quot; | Write-Host<br />Start-Sleep 2<br />Set-SPEnterpriseSearchTopology -Identity $newTopology<br />&quot;All Done,`nCheck the Search Administration page in Central Administration to verify&rdquo; | Write-Host</p>]]></content:encoded>
    </item>
    <item>
      <title>SharePoint 2013 Environment Latency and Network Test Script</title>
      <link>https://docs.microsoft.com/archive/blogs/alexst/sharepoint-2013-environment-latency-and-network-test-script</link>
      <pubDate>Thu, 12 Sep 2013 09:55:00 GMT</pubDate>
      <dc:creator><![CDATA[Alex Strachan]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/alexst/2013/09/12/sharepoint-2013-environment-latency-and-network-test-script/</guid>
      <description><![CDATA[The intra-farm latency requirement of SharePoint is one of the hardware requirement,...]]></description>
      <content:encoded><![CDATA[<p>The intra-farm latency requirement of SharePoint is one of the hardware requirement, described&nbsp;at <a href="https://technet.microsoft.com/en-us/library/cc262485.aspx">https://technet.microsoft.com/en-us/library/cc262485.aspx</a>&nbsp;</p>
<p>It can be difficult to test and is often left un-verified because short of having a server sit there and ping the rest of the farm for 10 minutes, there is no way to ensure that the environment is compliant.&nbsp; To solve this, I have written a script that leaves one of the servers sitting around pinging the rest of the farm for 10 minutes and reports back on whether the environment complies.</p>
<p>The Script performs the following tests:</p>
<p>&nbsp;- Check connectivity in the farm and make sure all servers are reachable. (this saves you from wasting 10 minutes waiting for the script to run only to find out the hosts weren't reachable)</p>
<p>&nbsp;- Open an ODBC connection to the database server. (This is always handy)</p>
<p>&nbsp;- Verify the environment meets the SharePoint hardware requirement that 99.9% of pings between servers in the farm take less than 1ms over a 10 minute period.&nbsp; For convenience, how long this runs can be changed by setting the $RunTime variable to a lower value.</p>
<p>&nbsp;</p>
<p>To run the script, either copy and paste the code into PowerShell_ISE and run it, or save it as a .ps1 file, right&nbsp;click it and select "Run with PowerShell".&nbsp; The second method requires the powershell execution policy to be "unrestricted" (to set, run <span style="color: #0000ff; font-family: Lucida Console; font-size: xx-small;"><span style="color: #0000ff; font-family: Lucida Console; font-size: xx-small;"><span style="color: #0000ff; font-family: Lucida Console; font-size: xx-small;">Set-ExecutionPolicy </span></span></span><span style="color: #8a2be2; font-family: Lucida Console; font-size: xx-small;"><span style="color: #8a2be2; font-family: Lucida Console; font-size: xx-small;"><span style="color: #8a2be2; font-family: Lucida Console; font-size: xx-small;">Unrestricted</span></span></span>).</p>
<pre class="scroll"><code class="cplusplus"> #####Set Local Variables<br /> #Set Host Names, or IP Addresses<br /> $hostnames = "10.0.0.1", "SomeHost"<br /> #SQL Server Name\Instance<br /> $SQLname = "SQL\Instance"<br /> #Configure Run Time in Minutes (helpful for debugging)<br /> $RunTime = 10<br /> #Configure an allowance for late pings (in ms, one way)<br /> $allowance = 0<br /> #####<br /> <br /> ### test connectivity ###<br /> Write-Host "Test Connectivity:"<br /> <br /> Write-Host "Testing Ping"<br /> $ping = New-Object System.Net.NetworkInformation.ping<br /> <br /> foreach($a in $hostnames){<br /> $status = $ping.send($a).Status<br /> if($status -ne "Success"){<br /> throw "Ping Failed to $($a)"<br /> }<br /> }<br /> Write-Host " - Succeeded `n"<br /> <br /> <br /> <br /> ### test SQL connectivity ###<br /> Write-Host "Testing SQL Connection"<br /> $SQLConnection = New-Object System.Data.Odbc.OdbcConnection<br /> $SQLConnection.connectionstring = "Driver={SQL Server};Server=$SQLname"<br /> $SQLConnection.open()<br /> if($SQLConnection.state -ne "Open"){<br /> throw "SQL Connection Failed"<br /> }<br /> Write-Host " - Succeeded `n"<br /> <br /> <br /> <br /> ### Intra-server latency consistency test ###<br /> Write-Host "Start network consistency test"<br /> <br /> <br /> $ScriptBlock = {<br /> # accept the loop variable across the job-context barrier<br /> param($InHost, $RunTime) <br /> <br /> $start = [DateTime]::Now<br /> $ping = New-Object System.Net.NetworkInformation.ping<br /> <br /> $PingResults = @()<br /> while([datetime]::now -le $start.AddMinutes($RunTime)){ <br /> $outping = $ping.send($InHost)<br /> if($outping.Status -ne "Success"){<br /> $PingResults = $PingResults + 100<br /> } else{<br /> $PingResults = $PingResults + $outping.RoundtripTime<br /> }<br /> Start-Sleep .1<br /> } <br /> return $PingResults<br /> }<br /> <br /> <br /> #run ping jobs in parallel<br /> foreach($i in $hostnames){<br /> Start-Job $ScriptBlock -ArgumentList $i, $RunTime -Name "$i.latency_test"<br /> }<br /> <br /> Write-Host "<br /> processing...`n"<br /> <br /> #wait and clean up<br /> While (Get-Job -State "Running") { Start-Sleep 5 }<br /> <br /> $output = @{}<br /> foreach($i in $hostnames){<br /> $output[$i] = Receive-Job -Name "$i.latency_test"<br /> }<br /> Remove-Job *<br /> <br /> #test results<br /> $LatencyTestFailed = 0<br /> foreach($i in $hostnames){<br /> $BadPings = $output[$i] | ?{$_/2 -ge 1 + $allowance}<br /> $PercentBadPings = $BadPings.length / $output[$i].Length * 100<br /> if($PercentBadPings -ge .1){<br /> "$i DOES NOT meet the latency requirements with $PercentBadPings % of pings &gt;$(1+$allowance)ms" | Write-Host<br /> $LatencyTestFailed = 1<br /> } else{<br /> "$i meets the latency requirements with $PercentBadPings % of pings &gt;$(1+$allowance)ms" | Write-Host<br /> }<br /> }<br /> if($LatencyTestFailed -eq 1){<br /> throw "Farm Latency Test Failed"<br /> } </code></pre>]]></content:encoded>
    </item>
    <item>
      <title>Installing SharePoint 2013 Prerequisites from a network share</title>
      <link>https://docs.microsoft.com/archive/blogs/alexst/installing-sharepoint-2013-prerequisites-from-a-network-share</link>
      <pubDate>Tue, 06 Aug 2013 14:34:00 GMT</pubDate>
      <dc:creator><![CDATA[Alex Strachan]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/alexst/2013/08/06/installing-sharepoint-2013-prerequisites-from-a-network-share/</guid>
      <description><![CDATA[Anyone who has tried to install SharePoint 2013 Prerequisites offline has probably come across this...]]></description>
      <content:encoded><![CDATA[<p>Anyone who has tried to install SharePoint 2013 Prerequisites offline has probably come across this article:</p>
<p><a href="https://technet.microsoft.com/en-us/library/ff686793.aspx">https://technet.microsoft.com/en-us/library/ff686793.aspx</a></p>
<p>This task can be somewhat difficult because assembling the prerequisites can be time consuming and running prerequisiteinstaller.exe with&nbsp;an arguments file presents some challenges (See the known issues section at the end of the above article).</p>
<p>To solve these, I have two scripts: one that runs prerequisiteinstaller.exe with inline arguments, eliminating the need to delete the startup task on the server and one that downloads all of the required files to a share.</p>
<p>&nbsp;</p>
<p>To install the prereqs from a share, run the following PowerShell script on the server you want to install SharePoint on with #path changed to the location of the network share where you have downloaded the SharePoint prerequisites:</p>
<pre class="scroll"><code class="csharp"> ##### Set Local Variables <br /> #Root Prerequisites Directory <br /> $PrereqRoot = "#Path&rdquo; <br /> #SharePoint Install Media Directory <br /> $SPRoot = "#Path&rdquo; <br /> ##### <br /> <br /> <br /> cd $SPRoot <br /> .\PrerequisiteInstaller.exe /SQLNCli:"$PrereqRoot\sqlncli.msi" /PowerShell:"$PrereqRoot\Windows6.1-KB2506143-x64.msu" /NETFX:"$PrereqRoot\dotnetfx45_full_x86_x64.exe" /IDFX:"$PrereqRoot\Windows6.1-KB974405-x64.msu" /Sync:"$PrereqRoot\Synchronization.msi" /AppFabric:"$PrereqRoot\WindowsServerAppFabricSetup_x64.exe" /IDFX11:"$PrereqRoot\MicrosoftIdentityExtensions-64.msi" /MSIPCClient:"$PrereqRoot\setup_msipc_x64.msi" /WCFDataServices:"$PrereqRoot\WcfDataServices.exe" /KB2671763:"$PrereqRoot\AppFabric1.1-RTM-KB2671763-x64-ENU.exe" <br /> </code></pre>
<p>To download all required files&nbsp;to a network share, run the following&nbsp;on an internet connected computer with access to the fileshare you want to use.&nbsp; Replace #path with the network location you want to store the prerequisites on:</p>
<pre class="scroll"><code class="cplusplus"> #Import Required Modules <br /> Import-Module BitsTransfer <br /> <br /> ##### Set Local Variables <br /> #Define the path of the target network share <br /> $TargetRoot = "#Path&rdquo; <br /> ##### <br /> <br /> #Create Target if needed <br /> if(!(Test-Path $TargetRoot)){ <br /> New-Item $TargetRoot -ItemType Directory -Force <br /> } <br /> 　 <br /> #Set the download targets. Note these URLs may be subject to change, check https://technet.microsoft.com/en-us/library/cc262485(v=office.15).aspx for a list of prerequisites. <br /> $PrereqURLs = ( <br /> #Microsoft .NET Framework version 4.5 <br /> "https://download.microsoft.com/download/b/a/4/ba4a7e71-2906-4b2d-a0e1-80cf16844f5f/dotnetfx45_full_x86_x64.exe", <br /> <br /> #SQL Server 2008 R2 SP1 Native Client <br /> "https://download.microsoft.com/download/9/1/3/9138773A-505D-43E2-AC08-9A77E1E0490B/1033/x64/sqlncli.msi", <br /> <br /> #Microsoft WCF Data Services 5.0 <br /> "https://download.microsoft.com/download/8/F/9/8F93DBBD-896B-4760-AC81-646F61363A6D/WcfDataServices.exe", <br /> <br /> # Microsoft Information Protection and Control Client (MSIPC) <br /> "https://download.microsoft.com/download/9/1/D/91DA8796-BE1D-46AF-8489-663AB7811517/setup_msipc_x64.msi", <br /> <br /> #Microsoft Sync Framework Runtime v1.0 SP1 (x64) <br /> "https://download.microsoft.com/download/E/0/0/E0060D8F-2354-4871-9596-DC78538799CC/Synchronization.msi", <br /> <br /> #Windows Management Framework 3.0 which includes Windows PowerShell 3.0 <br /> "https://download.microsoft.com/download/5/2/B/52B59966-3009-4F39-A99E-3732717BBE2A/Windows6.1-KB2506143-x64.msu", <br /> <br /> #Windows Identity Extensions <br /> "https://download.microsoft.com/download/0/1/D/01D06854-CA0C-46F1-ADBA-EBF86010DCC6/r2/MicrosoftIdentityExtensions-64.msi", <br /> <br /> #Windows Identity Foundation (KB974405) <br /> "https://download.microsoft.com/download/D/7/2/D72FD747-69B6-40B7-875B-C2B40A6B2BDD/Windows6.1-KB974405-x64.msu", <br /> <br /> #Windows Server AppFabric <br /> "https://download.microsoft.com/download/A/6/7/A678AB47-496B-4907-B3D4-0A2D280A13C0/WindowsServerAppFabricSetup_x64.exe", <br /> <br /> #CU 1 for AppFabric 1.1 (KB2671763) <br /> "https://download.microsoft.com/download/7/B/5/7B51D8D1-20FD-4BF0-87C7-4714F5A1C313/AppFabric1.1-RTM-KB2671763-x64-ENU.exe" <br /> ) <br /> <br /> #Download Files to Target <br /> "Downloading Files" | Write-Host <br /> <br /> foreach($URL in $PrereqURLs){ <br /> #The folder name should be the last "/" of the URL <br /> $Name = $URL.Split('/')[-1] <br /> <br /> #Current Download <br /> "$Name..." | Write-Host <br /> <br /> #Download Files, skip if unneccesary. <br /> if(!(Test-Path $TargetRoot\$Name)){ <br /> Start-BitsTransfer -Source $URL -Destination $TargetRoot\$Name -Priority High <br /> "Downloading...`n" | Write-Host <br /> } else{ <br /> "Already Downloaded`n" | Write-Host <br /> } <br /> } <br /> <br /> #Acknowledgements to Muawiyah Shannak whose script this is based off of. The original can be found here https://gallery.technet.microsoft.com/Script-to-SharePoint-2013-702e07df <br /> </code></pre>
<p>&nbsp;</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
  </channel>
</rss>