Archive for the 'Knowledge Base' Category

PowerGUI Editor 2.4 and AD cmdlets 1.4 compatibility issue

[UPDATE] This issue has been fixed in AD cmdlets 1.5.1 – please download the latest version of AD cmdlets here.

We have found a compatibility issue between PowerGUI Script Editor 2.4 and AD cmdlets 1.4 (these are the current versions at the time I am writing this post.)

SYMPTOMS

You execute a script which is using QAD cmdlets. The first time the script executes fine. However when you try to execute it again, the script fails with the “Object reference not set to an instance of an object.” error.

ISSUE

The issue is related to the way QAD cmdlets are handling initialization and unloading of the snapin.

SOLUTION

Set PowerGUI Script Editor to not reset PowerShell runspaces between the debug sessions:
1. Go to Tools / Options / Debug Options,
2. Select the Run all scripts in the same runspace option.
3. Restart PowerGUI Script Editor.

We are sorry for the inconvenience and are working on fixing the issue in the next releases.

PowerGUI Editor 2.1.1 and AD cmdlets 1.4 compatibility issue

[UPDATE] This issue got fixed in PowerGUI 2.2.

We have found that in some cases when you are using version 1.4.0 of QAD cmdlets inside PowerGUI Script Editor 2.1.1, and invoke a script with the cmdlets for the second time you may get the error: “Object reference not set to an instance of an object.

This is obviously very unfortunate and we are working on fixing the issue. In the meantime there are a couple of workarounds you can use:

A. Run Script Editor in MTA mode (if you don’t know what STA/MTA mean – this means that you would likely not notice any difference – but as a side-effect it might affect some script editor add-ons or your scripts using WPF)

To do this, just modify the PowerGUI Script Editor shortcut:

and add the -MTA switch to the command line:

B. Alternatively, you can set PowerGUI Script Editor to reset PowerShell runspace each time you start debugging:

1. In PowerGUI Script Editor, on the Tools menu, click Options,

2. In Debug Options, select Reset PowerShell runspace each time debugging is started.

Again, we appologise for the inconvenience and are working on a perminent fix.

Set -WhatIf ON by default

Making PowerShell safe by default is trivial. Ulf here suggested that “socially responsible” PowerShell needs to use -WhatIf by default for all operations, and actually perform the actions only if explicitly asked to do so.

To make PowerShell operate in this mode, all you need to do is set $WhatIfPreference variable to $true, and use -WhatIf:$false when you do want something to be executed. (colon is mandatory by the way – because this is a switch parameter).

Here’s my session (copy/pasted from PowerShell Console pane of PowerGUI Script Editor):

C:\> $WhatIfPreference
False
C:\> $WhatIfPreference = $true
C:\> $WhatIfPreference
True
C:\> Get-Process notepad

Handles  NPM(K)  PM(K)   WS(K)  Id  ProcessName
-------  ------  -----   -----  --  -----------
     63       3   2372    6668  66      notepad


C:\> Get-Process notepad | Stop-Process
What if: Performing operation "Stop-Process" on Target "notepad (4708)".
C:\> Get-Process notepad | Stop-Process -WhatIf:$false

Tags: , ,

Fastest way to retrieve AD objects

DontUseDefaultIncludedProperties is the AD cmdlets parameter you need when you want to get AD objects fast without extra properties you do not need. For example, I have just used it in my script to locate the largest groups in our Active Directory. Let’s talk about how effective it really is and how it works under the covers.

First, of all, let me prove that it is indeed very efficient. Here’s the same Get-QADUser run 100 times with and without the parameter:

[PS] C:\>Measure-Command { for ($i=0;$i -lt 100;$i++) { $a = Get-QADUser -SamAccountName dsotnikov -DontUseDefaultIncludedProperties } }

...
Seconds : 3
Milliseconds : 951
...


[PS] C:\>Measure-Command { for ($i=0;$i -lt 100;$i++) { $a = Get-QADUser -SamAccountName dsotnikov } }

...
Seconds : 7
Milliseconds : 526
...

That’s twice as fast with the parameter than it is without it!

Why? Because DontUseDefaultIncludedProperties makes the cmdlet only retrieve 2 attributes: distinguishedName и objectClass, whereas the cmdlet without it will go get quite a few other properties.

You can easily see which attributes got retrieved by running:
$a = Get-QADUser -SamAccountName dsotnikov -DontUseDefaultIncludedProperties
$a.Cache.AttributesInCache

The interesting thing is that the cmdlet is even smarter with subsequent use of the object. For most properties (to be specific, for all regular .NET properties of the object but not PowerShell dynamic NoteProperties), we will go and retrieve the property once you request it later on. E.g. this will actually work and give you the account description:

$a = Get-QADUser -SamAccountName dsotnikov -DontUseDefaultIncludedProperties
$a.Description

And this will retrieve a whole bunch of attributes:
Get-QADUser -SamAccountName dsotnikov -DontUseDefaultIncludedProperties | Format-List *

You can obviously keep using $a.Cache.AttributesInCache to check which ones we retrieve.

Pretty cool, isn’t it?

The only other thing I would note is the difference between:

Get-QADUser -SamAccountName dsotnikov -DontUseDefaultIncludedProperties

and

Get-QADUser dsotnikov -DontUseDefaultIncludedProperties

The former is way more efficient than the latter because the -SamAccountName parameter (or any other parameter besides the generic implied -Identity) lets us optimize the query specifically to search by that attribute rather than do the Ambiguous Name Resolution which we use otherwise. Be specific in your parameters and we will give you the fastest results!

Tags: , , , , , ,

Catch variable typos

Did you know that PowerShell has so called strict mode in which it can catch and report any use of uninitialized variables? I’ve started doing this while scripting and it made debugging scripts so much easier! Lot’s of typos and copy/paste issues simply get detected right away.

In PowerShell v1 you can turn this mode on by executing: Set-PSDebug –strict

In PowerShell v2 by doing: Set-StrictMode –version 1 or Set-StrictMode –version 2.

(See this great article explaining all the difference.)

To make this apply to all my debugging sessions, but not to command line and PowerGUI admin console, I did the following:

1. Opened my PowerShell profile:

Open-Profile

2. Added this code in there:

if ($host.Name -eq 'PowerGUIScriptEditorHost') {
    Set-StrictMode -Version 2.0
}

That’s it. Close the profile and restart the PowerGUI Script Editor.

P.S. Please forgive me the “if” workaround in common profile. In the future we will at some point start supporting a separate profile specifically for the script editor. This is the best practice and we’ll get there. 😉

Customize hotkeys in PowerGUI Script Editor

One of the hidden gems in PowerGUI Script Editor is the ability to fully customize its toolbars and hotkeys.

Say, you want to have a hotkey to collapse all regions in a PowerShell script – this could not be easier, just:

  1. On the Tools menu, click Customize.
  2. In the Customize dialog box, click the Keyboard tab.
  3. On the Keyboard tab, select the command you need.
  4. In the Press shortcut key(s), assign the hotkey you want.

Customize-Editor-Hotkeys

Other tabs of this dialog box are also useful:

  • Toolbars – lets you create your own toolbars.
  • Commands – lets you add buttons to existing toolbars by simply dragging them from the dialog box to the toolbar.

Hope this makes your PowerShell scripting even more enjoyable!

Clearing PowerShell runspace before debugging

Another PowerGUI Script Editor option I would like to highlight – is the ability to clear the PowerShell runspace each time you start debugging a script:

Editor_Reset_Runspace

Here’s the rule of thumb on picking the option you need:

Pick “Run all scripts in the same runspace” if you want the editor to behave like a PowerShell command line in which as you execute scripts and commands they leave the variables with their values assigned and available to whatever scripts you execute after that.

Pick “Reset PowerShell runspace each time debugging is started” if you want PowerGUI to completely clear PowerShell and (optionally) re-load your profile each time you start debugging. This basically emulates the situation when you start a new PowerShell window every time before executing a script – completely pristine environment with nothing left from whichever commands and scripts you executed before.

Use whatever model fits best and enjoy your scripting!

Tags: , , ,


My Recent Tweets

Legal

The posts on this blog are provided “as is” with no warranties and confer no rights. The opinions expressed on this site are mine and mine alone, and do not necessarily represent those of my employer - WSO2 or anyone else for that matter. All trademarks acknowledged.

© 2007-2014 Dmitry Sotnikov

February 2017
M T W T F S S
« Aug    
 12345
6789101112
13141516171819
20212223242526
2728  

%d bloggers like this: