Wednesday, October 22, 2014

Multiple Prompts SharePoint

If you are like me and many other SharePoint admins out there, you have run into this problem.

Scenario One: User launches SharePoint page from inside the domain and they get prompted for credentials.
Scenario Two: User launches SharePoint through VPN and gets prompted for credentials.
Scenario Three: Every resource or new site prompts the user for credentials.
Scenario Four: Extranet SharePoint site continually prompts for credentials.

In this days and age of (SSO) Single Sign On, users expect to log in once and then never be prompted again. Personally I have my Facebook and Google+ connected all over the place so that I can get into just about everything with-out prompting. Unfortunately internal corporate solutions require a little more security. Even more unfortunately SharePoint is extremely sensitive to security configurations, everything from the servers registry to the security on the databases. If you do a quick Google search you will see page after page of possible solutions, and for the most part they are all correct; but. they are correct for different causes. In most cases you are actually being plagued by several issues causing the same problem. So I will do my best to consolidate all of the solutions out there.

Solutions:
1. Internet Security - Ensure that your local security policy, group policy, or basic internet settings have your SharePoint site set in Trusted sites, or Local intranet. This is probably the easiest and least invasive thing you can do.

  • Make sure that you have a couple things configured properly for your local intranet, or trusted sites setting. First, ensure that 'Automatic Logon' is enabled. If your SharePoint URL contains periods then IE automatically assumes that it is on the internet. You can read more on the Technet site

2.Verify that you have correctly configured your alternate access mappings in SharePoint - 2013, 2010

3. Modify your Web.Config

<system.webServer> 
  <security> 
    <requestFiltering allowDoubleEscaping="true"> 
      <verbs allowUnlisted="true"> 
           <add verb="OPTIONS" allowed="false" /> 
          <add verb="PROPFIND" allowed="false" /> 
       </verbs> </requestFiltering> 
     </security> 
</system.webServer>


4. In IIS modify the web application to use NTLM instead of Kerboros

5. Dealing with an Extranet requires a little more configuration to your servers if you wish to avoid credential prompting.
From Technet
"Extranet users that want direct editing:
Use Forms Based Authentication (FBA) with persistent cookies – The only way to maintain direct-edit functionality and also not be prompted by the Office application is to implement a proxy/firewall server by using Forms Based Authentication with persistent cookies such as an Internet Security and Acceleration (ISA) server or a Forefront Threat Management Gateway.
Extranet users and direct editing is not needed:
Disable Client Integration or the OPTIONS/PROPFIND Verbs  -  If the site provides WebDAV functionality through another extension, the provider of that extension should be engaged. For example, to do this with Windows SharePoint Services (WSS), the site should be configured to disable Client Integration, or the OPTIONS and PROPFIND verb should be inhibited. (To inhibit the OPTIONS and PROPFIND verbs on Internet Information Services (IIS) version 6, remove the verbs from the registration line in the web.config file. On IIS 7.0, use the HTTP Verbs tab of the Request Filtering feature to deny the verbs.) Be aware that this approach will open the content in read-only mode because this approach disables direct-edit functionality."

Monday, June 9, 2014

How-To Automate boring Repetitive Android Tasks

Step 1: Install an Android Virtualization app called Bluestacks http://www.bluestacks.com/ or Andy http://www.andyroid.net/
note: you do not need an android phone to do this
Step 2: install your program or application inside of your emulator
Step 3: Install Ghost Mouse http://www.ghost-mouse.com/ or find another mouse click recorder that you like
Step 4: Run your app inside of your Android emulator
Step 5: Get to a point in the game or application process that can be repeated.
Step 6: Start your mouse recorder and complete the task in the application from start to finish, make sure that you end on the same screan as you started.
Step 7: Run your recorded Mouse macro as many times as you wish.

Monday, April 7, 2014

Cloud SharePoint Storage Reporting

Recently we had an issue with our Dynamics CRM pegging site quotas on our Cloud SharePoint. We had no monitoring, and nothing besides error messages notifying us that we could no longer add anything to our sites. I have personally tried to avoid our Cloud SharePoint solution, and focus on our On-Prem, but this became a very high priority to our management, very quickly. They asked me about any time of storage monitoring solutions, so of course I went out and "Googled" it, or if you drink the MS Kool Aid "Bing" it, lol. What I found was that most of the solutions for accomplishing what they wanted, came as part of a solution package. So I decided, lets try and save some money. My first thought was, "I know I can pull these stats on-prem, but who knows with cloud." Cloud SharePoint Powershell can be somewhat limited, but this time we lucked out.
So with that, lets get to the good stuff.
Step 1: If you haven't already done so,Download and set-up the "SharePoint On-Line Management Shell"
Step 2: If you want to schedule this then you need to set up an SPO Credential Script:

#Import the SharePoint Online Module
Import-Module Microsoft.Online.SharePoint.PowerShell -DisableNameChecking
#Hardcode your Credentials - Remember these must be your Cloud Creds
   $UserName = "TankCR@MyCreds.Com" $Password = "IWishIHadAG00d1"
#Set the Cred String
   $cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $(convertto-securestring $Password -asplaintext -force)
#Set your Cloud Admin URL
   $Url = "https://mysite-admin.sharepoint.com"
#And Finally Connect your Session
Connect-SPOService -url $url -Credential $cred 


Step 3: Build your reporting Script, a few things of note:

  •    I wrote this Script to create an excel specifically formatted XML file, then convert it to an XLSX, obviously there are more direct ways to accomplish this, but I am only a scripter, not a programmer ;)
  •    There are Patterns in this script that are necessary for formatting your output, you will need to modify these to your environment, and I will point them out when we get to them, Also here is a great tool to help you format and test your patterns. http://regex101.com/

#The First thing we must do is call our SPOCreds Script
$SPOCred = "PathToScriptFile such as C:\Scripts\SPOCreds.PS1"
invoke-expression -Command $SPOCred
#Now Set your Output File Locations, use your temp folder
$File = "$env:TEMP\usage.xml"
$File2 = "$env:TEMP\usage.xlsx"
#Now as I want this to be scheduled and Faced on my On-Prem SharePoint I set a net location to put the final copy
$NetLoc = "\\myonpremsharepoint.local\sites\reporting\Shared Documents\"


This is our first Pattern, in this Pattern I am grabbing three different sections of the URL's so that I can sort my report automatically based on the core part that is similar across my sites. You will need to modify this to your site use http://regex101.com/ if you need help doing so...

$Pat = "(.*)(CRM.*_?)(_.*)"

Now we grab and store our sites in a sorted manner, I am first sorting by the pattern we set up top, then I am sorting by the sites using the highest percentage of their quotas.
$Sites = (Get-SPOSite -Detailed -ErrorAction Ignore -limit all)|sort -Descending -Property {$_.URL -replace $Pat,'$2'},@{e={[INT]($_.StorageUsageCurrent)/[INT]($_.StorageQuota)}}

Now the Excel formatting requires a proper count on our Rows or it will error out, so we are going to grab a count on how many sites we have:
$Number = $Sites.Count
OK, lets create our XML File, this is the initial formatting that it will need to understand what it is, and what styles we are using.
(
 '<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:html="http://www.w3.org/TR/REC-html40"
 xmlns:x2="http://schemas.microsoft.com/office/excel/2003/xml"
 xmlns:udc="http://schemas.microsoft.com/data/udc"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:udcxf="http://schemas.microsoft.com/data/udc/xmlfile">
 <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
  <Author>Kristopher Roy</Author>
  <LastAuthor>'+$env:USERNAME+'</LastAuthor>
  <Created>'+(get-date)+'</Created>
   <Version>15.00</Version>
 </DocumentProperties>
 <OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
  <AllowPNG/>
 </OfficeDocumentSettings>
 <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
  <WindowHeight>12435</WindowHeight>
  <WindowWidth>25500</WindowWidth>
  <WindowTopX>0</WindowTopX>
  <WindowTopY>0</WindowTopY>
  <ProtectStructure>False</ProtectStructure>
  <ProtectWindows>False</ProtectWindows>
 </ExcelWorkbook>
 <Styles>
  <Style ss:ID="Default" ss:Name="Normal">
   <Alignment ss:Vertical="Bottom"/>
   <Borders/>
   <Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#000000"/>
   <Interior/>
   <NumberFormat/>
   <Protection/>
  </Style>
  <Style ss:ID="s27" ss:Name="Bad">
   <Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#800000"/>
   <Interior ss:Color="#FFC7CE" ss:Pattern="Solid"/>
  </Style>
  <Style ss:ID="s26" ss:Name="Good">
   <Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#008000"/>
   <Interior ss:Color="#C6EFCE" ss:Pattern="Solid"/>
  </Style>
  <Style ss:ID="s62" ss:Name="Hyperlink">
   <Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#0066CC"
    ss:Underline="Single"/>
  </Style>
  <Style ss:ID="s28" ss:Name="Neutral">
   <Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#993300"/>
   <Interior ss:Color="#FFEB9C" ss:Pattern="Solid"/>
  </Style>
  <Style ss:ID="s63">
   <Borders>
    <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="2"/>
    <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="2"/>
    <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="2"/>
    <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="2"/>
   </Borders>
   <Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#000000"
    ss:Bold="1"/>
   <Interior ss:Color="#D0CECE" ss:Pattern="Solid"/>
  </Style>
  <Style ss:ID="s64">
   <Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
  </Style>
  <Style ss:ID="s66" ss:Parent="s62">
   <Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
  </Style>
  <Style ss:ID="s68" ss:Parent="s26">
   <Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
   <NumberFormat ss:Format="0%"/>
  </Style>
  <Style ss:ID="s70" ss:Parent="s28">
   <Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
   <NumberFormat ss:Format="0%"/>
  </Style>
  <Style ss:ID="s72" ss:Parent="s27">
   <Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
   <NumberFormat ss:Format="0%"/>
  </Style>
    <Style ss:ID="s90" ss:Parent="s62">
   <Alignment ss:Horizontal="Center" ss:Vertical="Bottom"/>
   <Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#0066CC"
    ss:Bold="1" ss:Underline="Single"/>
   <Interior ss:Color="#FFE699" ss:Pattern="Solid"/>
  </Style>
 </Styles>
 <Worksheet ss:Name="Site Quotas">
  <Table ss:ExpandedColumnCount="9" ss:ExpandedRowCount="'+($Number+1)+'" x:FullColumns="1"
   x:FullRows="1" ss:DefaultRowHeight="15">
   <Column ss:AutoFitWidth="0" ss:Width="100.5"/>
   <Column ss:Width="441.75"/>
   <Column ss:Width="247.5"/>
   <Column ss:Width="33.75"/>
   <Column ss:Width="41.25"/>
   <Column ss:Width="73.5"/>
   <Column ss:Width="77.25"/>
   <Column ss:Width="117.75"/>
   <Column ss:Width="105"/>
   <Row ss:AutoFitHeight="0">
    <Cell ss:StyleID="s63"><Data ss:Type="String">Title</Data></Cell>
    <Cell ss:StyleID="s63"><Data ss:Type="String">URL</Data></Cell>
    <Cell ss:StyleID="s63"><Data ss:Type="String">Owner</Data></Cell>
    <Cell ss:StyleID="s63"><Data ss:Type="String">Quota</Data></Cell>
    <Cell ss:StyleID="s63"><Data ss:Type="String">Percent</Data></Cell>
    <Cell ss:StyleID="s63"><Data ss:Type="String">QuotaWarning</Data></Cell>
    <Cell ss:StyleID="s63"><Data ss:Type="String">ResourceQuota</Data></Cell>
    <Cell ss:StyleID="s63"><Data ss:Type="String">ResourceQuotaWarning</Data></Cell>
    <Cell ss:StyleID="s63"><Data ss:Type="String">StorageUsageCurrent</Data></Cell>
   </Row>')> $file


We are now going to iterate through each site collection and write them to our xml file. But of course we first need to set some parameters on how this will occur so that we can get the results we want.
FOREACH ($Site in $Sites){ 
#Gets the Site Owner, if it can't for some reason it sets the variable to just "Farm"
$Owner = if(($Site.Owner -eq $NULL) -or ($site.Owner -eq "")){$Owner = "Farm"}ELSE{$Site.Owner}

#Another Pattern, this one is to break down the URL's so that we can set the Title if one doesn't exist
$Pat = "(https?.\/\/)(\w*-?\w*)(.*)?"
if($Site.Title -eq $NULL -or $Site.Title -eq ""){$Title = ($Site.url -replace $pat,'$2')}ELSE{$Title = $Site.Title}

#Gets the Usage Percentage then sets the excel style so that higher percentages get color coded
$BasePercent = ($Site.StorageUsageCurrent / $Site.StorageQuota)
If ($BasePercent -ge ".75"){$Percent = ''+$BasePercent+''}
If (($BasePercent -lt ".75") -and ($BasePercent -ge ".60")){$Percent = ''+$BasePercent+''}
If ($BasePercent -lt ".60"){$Percent = ''+$BasePercent+''}


Now Lets write our rows formatted to our XML file.
#I wanted any sites with Prod in them to be highlighted, you can change this to whatever you like $URLCODE = IF($Site.URL -ilike "*Prod*"){"s90"}ELSE{"s66"} add-content $File ('') add-content $File (''+($Title)+'') add-content $File (''+''+($Site.url)+'') add-content $File (''+($Owner)+'') add-content $File (''+($Site.StorageQuota)+'') add-content $file $Percent add-content $File (''+($Site.StorageQuotaWarningLevel)+'') add-content $File (''+($Site.ResourceQuota)+'') add-content $File (''+($Site.ResourceQuotaWarningLevel)+'') add-content $File (''+($Site.StorageUsageCurrent)+'') add-content $File '' }

The last thing that we will write to our XML file is an XML component that closes it out.
add-content $file (
'    </Table>
  <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
   <Unsynced/>
   <Print>
    <ValidPrinterInfo/>
    <HorizontalResolution>600</HorizontalResolution>
    <VerticalResolution>600</VerticalResolution>
   </Print>
   <Selected/>
   <LeftColumnVisible>1</LeftColumnVisible>
   <FreezePanes/>
   <FrozenNoSplit/>
   <SplitHorizontal>1</SplitHorizontal>
   <TopRowBottomPane>1</TopRowBottomPane>
   <ActivePane>2</ActivePane>
   <Panes>
    <Pane>
     <Number>3</Number>
     <ActiveCol>1</ActiveCol>
    </Pane>
    <Pane>
     <Number>2</Number>
     <ActiveRow>10</ActiveRow>
     <ActiveCol>2</ActiveCol>
    </Pane>
   </Panes>
   <ProtectObjects>False</ProtectObjects>
   <ProtectScenarios>False</ProtectScenarios>
  </WorksheetOptions>
 </Worksheet>
</Workbook>')


At this point we will grab our file and convert it to a true excel file so that you can use it with the excel viewer web-part, we will also copy it to your network location and then delete it off your hard drive. (Important Note, to convert it to XSLX you must have excel installed on the machine where you run this)
 $objExcel = new-object -comobject excel.application
$UserWorkBook = $objExcel.Workbooks.Open($file)
$UserWorkBook.SaveAs($file2,51)
$UserWorkBook.Close()
copy $file2 $NetLoc
remove-item $file
remove-item $file2


Files:
SCsToExcel.ps1   SPOCreds.ps1

SharePoint 2013 Load Testing

If you have ever wanted to load test your SharePoint Environment I would highly recommend this step by step video done at SPC2014 by Todd Klindt and Shane Young. I will keep my eye out for a non-video step-by-step, or possibly write one out myself.
http://channel9.msdn.com/Events/SharePoint-Conference/2014/SPC381