Archive for the 'KB' Category

New in PowerShell 3: Parse HTML without IE object (unless a local file)

Remember how in PowerShell v1 and v2 we used to have to create Internet Explorer object each time we wanted to parse HTML page? This kind of works but has a few inconveniences such as having to insert Start-Sleep every now and then because IE can be busy and fail if you request too much from it too quickly.

In PowerShell v3, for web pages, things become much easier. Just do:

$p = Invoke-WebRequest "https://dmitrysotnikov.wordpress.com"

And $p.ParsedHtml.body will let you iterate though all web page elements!

However, there is a scenario in which you will have to revert to the old IE ways – local files. If the HTML file is on your local disk, $p will not have the ParsedHtml property. And you will have to use the IE COM object like you did in earlier versions of PowerShell:

$ie = new-object -com "InternetExplorer.Application"
# The easiest way to accomodate for slowness of IE
Start-Sleep -Seconds 1
$ie.Navigate("D:\SavedPage.htm")
# The easiest way to accomodate for slowness of IE
Start-Sleep -Seconds 1
$ParsedHtml = $ie.Document

Happy scripting!

Fix PowerGUI shortcuts in Start menu

ISSUE

PowerGUI 3.0 accidentally shipped with Windows Start menu shortcuts being called just “Administrative Console” and “Script Editor”. Which means that if you are used to starting applications by typing keywords in Start menu, you won’t be able to find the tools by typing PowerGUI:

SOLUTION

Open PowerGUI Script Editor (or native PowerShell command line), run the following command in the PowerShell Console window:

dir “$($env:ProgramData)\Microsoft\Windows\Start Menu\Programs\PowerGUI” | where {$_.Name -notmatch “PowerGUI”} | Rename-Item -NewName {“PowerGUI ” + $_.Name}

This will rename the shortcuts for you:

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.

Unblocking PowerGUI Add-Ons and PowerShell Modules

When trying to use a Script Editor add-on or a PowerShell module or script you downloaded from the internet, you might every now and then get an error message like this:

Import-Module : File C:\Users\dsotnikov\Documents\WindowsPowerShell\Modules\Add-on.HelpBrowser\Add-on.HelpBrowser.psm1 cannot be loaded. The file C:\Users\dsotnikov\Documents\WindowsPowerShell\Modules\Add-on.HelpBrowser\Add-on.HelpBrowser.psm1 is not digitally signed. The script will not execute on the system. Please see “get-help about_signing” for more details..At line:1 char:184+ @(‘C:\Users\dsotnikov\Documents\WindowsPowerShell\Modules\Add-on.HelpBrowser\Add-on.HelpBrowser.psd1’) | Where-Object { @(Get-Module | %{$_.Path} ) -notcontains $_ } | %{ Import-Module <<<<  $_ }    + CategoryInfo          : NotSpecified: (:) [Import-Module], PSSecurityExc    eption    + FullyQualifiedErrorId : RuntimeException,Microsoft.PowerShell.Commands.ImportModuleCommand

This happens when the downloaded file comes from the internet, is not signed and thus conflicts with your PowerShell execution policy (e.g. RemoteSigned).

If you do trust this particular add-on/module/script to not be malicious (comes from a trusted source, has been inspected and so on), the workaround is quite easy – simply right-click the file (or the entire zip file if the files were zipped) and click Unblock in the Properties dialog box:

(You can also unblock files from PowerShell command-line – and in bulk! – by using Remove-DownloadFlag from PoshCode module.)

Hope this helps!

Dmitry

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: , , , , , ,

PowerShell Script Templates

Adding standard header with disclaimer, copyright, and so on to your scripts is very easy. If you would like to (or have to – because of your company’s policies) use a certain template for your scripts – just define is as a code snippet in PowerGUI Script Editor.

Once you do that, the template is just a click- (or Ctrl-I-) away:

header_snippet(Note that snippets are alphabetically sorted so using underscore to get your ahead of others is a valid trick.)

And then, once you select the snippet you would probably get something like:

header_addedHopefully, this will save you a few extra seconds a day wasted on meaningless copy/paste. 🙂

Detailed instructions on adding your code snippets can be found here.

Add your code snippets to PowerGUI

Want to add your PowerShell code snippets to PowerGUI Script Editor?

snippet_insert

It is actually as easy as adding your xml .snippet file to the C:\Program Files\PowerGUI\snippets folder.

You can create a new file manually or use any Visual Studio-compatible snippet editor. I am using Snipp Dogg which is a free open source project on codeplex. So my instructions below are using this tool but anything else would do.

1. Run the tool as Administrator (or it would not be able to save to Program Files if you are on Vista or later.)

2. You can see and study any of the snippet files shipped with PowerGUI:

PowerShell_Snippets

3. Click the New button to create a new snippet and then paste your code into the central pane – in my example I start with advanced function code from PowerShell v2 example:

new_snippet

4. If you want your snippet to have placeholders for certain variable names, parameters, and so on, you need to replace each of them with $some_kind_of_id$. In addition to that you can put $selected$ in front of the one you want to become selected once the snippet is inserted.

In my example, I am making the function name and the variable name these snippet parameters (in snippet lingo “literals”) and make the function name selected by default:

params

5. Fill out other snippet parameters in the right-hand pane (Snipp Dogg does not have powershell as a language option – shame on them – so either change it in the xml file later on or just leave it as csharp – PowerGUI does not check this field):

sniippet_description

6. Expand the Literals collection and click New to add a new literal (remember: we need to specify two):

snippet_new_literal

7. Fill out and save (by clicking OK) both functionname and param:

function_name_literal

snippet_param_paramname

8. Save the snippet to the C:\Program Files\PowerGUI\snippets folder (requires admin rights in Vista and later):

snippet_save

9. Start PowerGUI Script Editor and insert the snippet:

snippet_insert

snippet_inserted

That’s it! Happy scripting! 😉

Tags: , , ,

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

September 2020
M T W T F S S
 123456
78910111213
14151617181920
21222324252627
282930  

%d bloggers like this: