Decreasing Indentation of Visual Studio Lines


There are a few articles already out on the Internet, but every time I need them, it takes me forever to find them (have you heard of bookmarks?). I decided to write my own post so I know I’ll always be able to find it.

Scenario

I’ve just copied and pasted about 100 lines of PowerShell code to a script I’m writing, but the indentation is way too far in for this. I’d love to just select all of it and use a key combo like indenting.

Solution

The solution is easy, just use this key combo

Shift + Tab

That’s it! Why can I never remember this? Now I don’t have to. I just need to remember I wrote this article.

Error: The Search Display Templates Are Not Present on this Site Collection


I’m in the process of testing the new SharePoint Online Hybrid Search capabilities that have been released with the August 2015 Cumulative Update (KB3055009). I ran into an issue that I was able to resolve pretty quickly, but I wanted to share the solution I found.

Hybrid Search Information (This is in preview, do not deploy to production environments)

Issue

After running the Onboarding Script after all the errors had been dealt with, I attempted to create a new Result Source in my newly created Hybrid Search Service Application.

Here’s what I am doing

I am creating a result source to show only Remote (cloud) search results

  1. In Central Administrator of my on-premise farm I navigate to the newly created Hybrid Search Service Application
  2. Click Result Sources link in the left navigation
  3. Click New Result Source
  4. I enter the following settings
    • Result Source Form
  5. Click the Launch Query Builder button (see above)
  6. If it doesn’t appear automatically, click the Test Query button and you’ll see the following error below
    • Query Builder Error
    • Full Error Text: Build Your QueryThe Search display templates are not present on this site collection. To add them, you need to activate the “Search Server Web Parts and Templates” feature on the Site Collection Features page.Correlation ID: 13783c9d-e6d3-1051-1690-22b8fb473c46

Solution

Essentially, SharePoint is telling us that it doesn’t have all the Search features enabled in Central Administration. I have no idea why, since search and the query builder were working prior. The resolution for me was to run the below command.

  1. Open the SharePoint Management Console as Administrator
  2. Enter the following command
    1. Enable-SPFeature SearchWebParts -URL http://centraladministration:PortNumber
  3. Now try the Query Builder again and it should work

If you have questions or this doesn’t solve the issue for you please post a comment.

Creating Desktop Shortcuts to PowerShell that Pass a Parameter


Previously I wrote about how to create a Dynamic PowerShell Profile which allows you to choose upon execution of PowerShell whether you are running your scripts in a DEV state or PROD state.

In this article, I’ll go one step further and show you how to create a custom Desktop Shortcut that will automatically pass the parameters you’ve identified in your Dynamic PowerShell Profile so you don’t need to enter them when you double click the shortcut.

Scenario

In this scenario, I want to have 2 desktop shortcuts. One that will open PowerShell using my DEV profile and one that will open my PROD profile. Technically, the shortcuts are opening the same PowerShell executable, and are running the same profile. The difference is in the parameter/s it is passing when it executes.

Instructions

  1. Click Start and Enter “PowerShell” into the search bar (this is assuming you’re running Windows 7 or higher)
  2. Right Click the “Windows Powershell” result
  3. Choose Send To > Deskop (create shortcut)
  4. Right Click the new shortcut on your desktop
  5. Click Properties
  6. Click the Shortcut tab
  7. Place or cursor at the end of the text in the Target: field
  8. Enter the following text:  -noprofile -noexit -command . $profile -inpType DEV
  9. The entire string will now look similar to: %SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -noprofile -noexit -command . $profile -inpType DEV
  10. Click OK

What Did We Just Do?

Let’s take a look at the additional text we added and break it down.

-noprofile = This tells powershell not to load the $profile we have created and associated with PowerShell. We’re not loading this initially because we want to easily pass a parameter without needing user interaction

-noexit = This tells PowerShell to stay open after executing. If you don’t include this, you’ll see the PowerShell application open and then it will disappear just like that. Allowing PowerShell to close right away is useful when you’re doing silent installs or other tasks that you don’t want/need the user to interact with the application once the process is complete.

-command . $profile = This tells PowerShell to run a command which is the . $profile command which is actually telling PowerShell to run the $profile script.

-inpType DEV = This tells PowerShell that you’re going to pass the $profile script a parameter with is named “inpType” which is created in the $profile script we created previously (you can name your parameters whatever you want). DEV is the parameter itself. You could pass PROD if you wanted instead.

Now, you can change the name of the shortcut to something like “DEV – Windows PowerShell” then copy and paste, rename the new one as “PROD – Windows PowerShell” then change the Target path entry to reflect a PROD parameter entry and now you have 2 shortcuts that will allow you to quickly run in DEV or PROD mode.

I hope this is useful to you. If you have questions or need assistance, feel free to post a question. If you need help adding to your profile, by all means post the question and hopefully I’ll be able to help you out.

Dynamic PowerShell Profile


If you’re writing PowerShell scripts the right way, you’re testing your scripts against a Test, or DEV environment prior to deploying those scripts to your Production environment (You ARE testing your scripts right?). If you’re using source control for your scripts (You ARE using source control for your scripts right?) then you’re likely using a DEV branch for your in progress script and then when all is ready you can Merge that into MAIN or whatever you call your production branch.

NOTE: If you aren’t using source control, branching & merging, and testing, you’ve probably got bigger problems than your PowerShell profile.

Scenario

If you are able to remotely run your code against your servers or if you’re like me and you’re managing Office 365, you’re running your test scripts and your production scripts on the same workstation.

Some of the common repeatable steps I have to take to differentiate my DEV and PROD instance are to change my directory I’m running my scripts from and since I write a lot of Modules, I need to ensure I’m using the correct Modules.

Out of the box, you’re going to have to manually change your directory and go in and add a temporary module directory depending on where your DEV and PROD modules are stored. I can write a script to do this and that’s what I’ve done, but instead of calling that script manually, why not incorporate it into your profile?

Solution

Below is a simple profile I’ve created for my workstation that allows me to determine what environment I’m working in when I run PowerShell. Now, I do nothing different when I open my Windows PowerShell. When it executes it runs the $profile and my script executes prompting me to enter “DEV” or “PROD” based on what I’m working on at the time.

Here’s the script you will copy and paste into your $profile file on your workstation. See below for the instructions.

param(
	[Parameter(Mandatory=$True,HelpMessage="Enter the environment you will be working on (DEV or PROD)")]
	[String]$inpType
)

function Prompt
{
 	switch($inpType)
	{
		"DEV"
		{
			$color = "Yellow"
		}
		"PROD"
		{
			$color = "Green"
		}
		Default
		{
			Write-Host "ERR -- Environment Type entry not valid." `n -foregroundcolor Red
		}
	}
	Write-Host ($inpType + ">") -noNewLine -foregroundColor $color
	Return " "
}
if($inpType -eq "DEV")
{
	$env:PSModulePath = $env:PSModulePath + ";<ENTER YOUR DEV MODULE PATH>"
	Set-Location "<ENTER YOUR DEV SCRIPT DIRECTORY>"
	prompt
}
Else
{
	$env:PSModulePath = $env:PSModulePath + ";<ENTER YOUR PROD MODULE PATH>"
	Set-Location "<ENTER YOUR PROD SCRIPT DIRECTORY>"
	prompt
}
clear

What is this script doing?

There are three specific tasks this script is doing.

  • Add Temporary Module Path (based on Parameter entry)
  • Sets Current Directory (based on Parameter entry)
  • Changes Prompt text and color (based on Parameter entry

Instructions

Follow these steps to include the script above into your Windows PowerShell Profile. Note there are pieces you need to modify in the script above that are wrapped in <>’s. You’ll need to change the paths to represent your own locations.

  1. Open Windows PowerShell
  2. Verify you have a $profile created. Click for instructions and information about PowerShell Profiles
  3. Edit your profile by entering the following command: notepad $profile
  4. Copy the code above (make sure you’ve changed paths to represent your paths) and paste the code into the $profile notepad file
  5. Save
  6. Close PowerShell and Re-Open
  7. You should see a prompt similar to the image below

Profile Prompt

Once you’ve entered the environment, your PowerShell prompt should look like the below image

Profile DEV Prompt

Verify Your Profile Environment

It’s wise to verify you got the profile paths correct. Test that the $profile applied the variables as expected by running the following commands

Module Path

$env:PSModulePath

The information returned will be a semi-colon separated result including all current module paths. Your newly added path should be included in this

Current Directory

Get-Location

This should return the current directory your PowerShell session is set to right now. This should reflect your environment path you entered.

Prompt

You should be able to see the prompt is different depending on the input you chose.

PROD = PROD>

DEV = DEV>

If I Entered “DEV” Do I Have to Close PowerShell to get into “PROD”

No, you do not have to close out, though it might not be a bad idea depending on all the stuff you add to the profile. You can switch easily by entering the following command

. $profile PROD

There is a little bit of error handling, but not much in this script so be aware that you will want to augment this script if you want more error handling.

What can I do with this?

The sky is the limit. If you want to have specific modules loaded or snap-ins you know you’ll use, go ahead and add them. Just be warned, if you add too much stuff, it could slow the overall load time down as well.

Check back to my blog, I’ll show you how you can create a desktop shortcut to automatically enter the parameter so you can quickly get into your DEV or PROD PowerShell profile without entering anything.

You Know You’re A Nerd When…


You know you’re a huge nerd when… You send jokes to your co-workers complaining about leadership via Lync using fake PowerShell commands.

Wow! It’s getting really nerdy up in here today. 🙂

Joke of the day today.

Set-SPExpert -Identity “Leadership” -Force -ErrorAction SilentlyContinue

Wow! That’s so bad.

Microsoft Ignite Activity Overload


I am so excited. On Sunday I get to hop on a plane headed for Chicago for the Microsoft Ignite conference May 4th-8th. Of all the nerd inspired things one could do, going to a Microsoft technology conference has got to be at the top of the list.

I’m learning pretty quickly, though that nerds apparently know how to party, or at least to appear to know how to party. I’ve not been to a conference of this size, so having to pick and choose my after-hours entertainment from the slew of options available to me is a bit daunting, but a nice problem to have.

I, and my employer are hoping I’ll come away from this 5 day experience with some valuable knowledge, skills, and contacts regarding SharePoint, Office 365, OneDrive for Business, Skype for Business, Windows PowerShell and so many other technologies.

I’m not sure if I have any readers that are also going to Ignite, but if you are, what sessions are you looking forward too and what after-hours stuff are you hoping to do? I’m really hoping I’ll bump elbows with someone important who has extra tickets to one of the Wild vs. Blackhawks playoff games as I’d love to see my team when I’m in Chicago.

For those of you not a member of the nerd world of enterprise technologies, what are your recommendations for things to do in the great Windy City of Chicago USA next week? Any great restaurants you can recommend? We’re going to be downtown in the Michigan ave area so I’m looking for great ideas there?

If any of you are going, I’d say we should meet up and have a drink, but let’s be honest, are we really going to do that? Do you really want to meet me? Of all the people out there, I’ll be honest, it’s not going to be that awesome meeting me… ha ha or is it? If you’re willing to go to a midnight viewing of the new Avengers: Age of Ultron (2015) movie with me, then I’ll meet up with pretty much anybody, or you have tickets to the Hawks game, just don’t plan on murdering me please, that would be a pretty big downer.

Who’s Managing Permissions?


Find_AccessRequestIt has been a while since I’ve posted anything, but that doesn’t mean I’ve been sitting around twiddling my thumbs all day. Here’s a quick SharePoint post. Stay tuned for more as we ramp up our new environment and we migrate to it. There should be some interesting stuff. (I hope)

Recently we’ve been getting requests from our messaging team (MS Exchange 2010) to remove/change e-mail addresses assigned in the Access Request field of our SharePoint sites as the domain has changed. This wouldn’t be an issue but we have 600+ Site Collections with 6,000+ individual sites. This of course means manually searching for the particular sites that have the offending e-mail address would be impossible. Thus, I have created a simple to use PowerShell script to iterate through every single SPWeb in the desired Web Application and return all Webs that have the user submitted e-mail address. Below is the full code.

**Note: I did not handle errors in this script. The most common error you will get is if you have Site Collections set to Read Only, or No Access. You will need to either reset their lock state or write logic to identify this and handle.

Step 1

  • Copy below code and save to file named Find_AccessRequest.ps1

clear
#End user is required to input Web Applciation, E-mail Address, and Export File Path
#Region User variable input
$inpWebApp = Read-Host "Enter the Web App Friendly Name"
$webapp = Get-SPWebApplication $inpWebApp
$inpEmail = Read-Host "Enter the e-mail address to search for"
$inpExportPath = Read-Host "Enter the path for the export"
#endRegion

#Gets the current date and time for the FilePath
$date = Get-Date -UFormat %y%m%d.%H.%M.%S
$path = $inpExportPath + "/" + $date + "_AccessRequest_" + $inpEmail + ".csv"

#Iterates through each site collection within the specified Web Application
foreach($spsite in $webapp.Sites)
{
	#Writes the current Site Collection to the console for troubleshooting purposes
	Write-Host "SC: " $spsite.URL

	#Iterates through each web within the site collection
	foreach($web in $spsite.AllWebs)
	{
		#Web must have permissions broken, request access enabled, and the e-mail must match the user input
		if( $web.HasUniqueRoleAssignments -and $web.RequestAccessEnabled -and $web.RequestAccessEmail -eq $inpEmail) 
		{
			#Writes the results to the console and exports to a CSV file
			Write-Host "	" -NoNewline; Write-Host $web.URL -BackgroundColor White -ForegroundColor Black
			Write-Output $web.URL | Out-File -Append -FilePath $path
		}
	}
}

Step 2

  • Run the file created in Step 1
  • Enter the following information (see screenshot below)
    • Web Application Name
    • E-mail Address to find
    • Path for export (do not include filename, the script will create the name)

Find_AccessRequest_Input

Step 3

  • As the script runs it will provide the following information on the console screen in real time (see below)
    • Site Collection URL
    • SP Web URL that has a matching e-mail address in the Access Request field (highlighted in White)

Find_AccessRequest-ResultsConsole

  • Now navigate to the Export location you entered. You should see a file with the following name:

yymmdd.hh.mm.ss_AccessRequest_<email address>.csv

  • Open the file. There will be a single column of data. The data will be each SPWeb that has the supplied e-mail address configured as the Access Request e-mail. It will only include Webs that have their permissions broken, which enables the web manager to configure the Access Request field independent of the parent site/web.

I hope this helps someone out there who needs to find an e-mail address in the Access Request field. I may at some point add to the script to allow for changing the address in bulk, but so far our need has only resulted in a few webs at a time.

As always, please a comment letting me know if this helped or if you have ideas to improve upon the script or for ideas for future scripts.

Thanks.