Scott H’s RSS download script


Here is a script that can grab items from a rss feed:
mkdir “~\Desktop\AzureFriday”
cd “~\Desktop\AzureFriday”
[Environment]::CurrentDirectory=(Get-Location PSProvider FileSystem).ProviderPath
$a = ([xml](new-object net.webclient).downloadstring(”))
$ | foreach{
$url = New-Object System.Uri($_.enclosure.url)
$file = $url.Segments[1]
“Downloading: “ + $file
if (!(test-path $file))
(New-Object System.Net.WebClient).DownloadFile($url, $file)
This is a great example of using powershell with the ,net framework.

PowerShell 101 Part 2

Powershell is very useful for quick queries or repeatable scripts.

Scripts can be shared, tested, adapted and reused.

Here are a few key points about powershell:

  • It does have an odd syntax – but does have good reasons for this.
  • It is very consistent (except about brackets)
  • It is secure by default
  • Everything is an object
  • Everything is discoverable
  • Help is always available for those that ask
  • Pipelines are powerful but are not the solution to everything
  • Cmdlets are intended to be combined.

Simple Functions

I’ll start with a function example.

function Test($a, $b)
“$a – $b”

This is a function written in the simple form (there are two advanced variations which I won’t go into here).

To call this you should use the following:

Test a b

This is the positional form of parameters.

Alternatively you could use:

Test -a a -b b

This is the named parameter form.

You can of course mix these up.

Test -b b a

You can even use a dictionary object to pass the parameters in:

$var = @{a=1;b=2}

test @var

However you will get odd behavior if you try and use brackets or commas:


1 2 –

Test 1,2

1 2 –

This is because brackets and commas create lists.

There is an exception to this when you are calling methods on .net objects.


Here brackets and commas are required.

Powershell even gives help details about custom functions.

get-help test


Test [[-a] <Object>] [[-b] <Object>]




All of the built in functions (called cmdlets) behave in exactly the same way as custom functions.

They have a very strong naming convention: Verb-Noun

The verb is one of a given list (get-verb gives you the list, currently there are 98)

The noun is by convention singular.

They are intended to be composed in a pipeline.

The rule is anything not bound to a variable or cast to null is passed down the pipeline.

The following is how I determined how many verbs there are:

get-verb | Measure-Object | select count

Comparison operations.

Powershell uses the normal > and < symbols for file redirection (because it is backwards compatible with dos).

This means that you need to use the switch versions of these.

This is where the built in help comes in handy:

get-help about_ | Out-GridView

get-help about_comp -ShowWindow


Some commands have short aliases:


These typically map back to the dos or unix command that they resemble.


The command prompt in powershell forms a read-evaluate-print-loop.


1..10 | % {write-host “Hello $_”}

1..10 | sort -Descending | % {write-host “Hello $_”}

Each command in the chain will act as soon as it gets some data.

However greedy operators (such as sort) need the source to finish before passing parameters on.

Useful Cmdlets





Powershell 101 – Setup

This is the first in a series of articles that I am going to write about an introduction to powershell.

However to start with I’ll give a useful option for the Powershell Integrated Scripting Environment (ISE – pronounced ICE).

$psISE.Options.FontSize = 20

This allows the editor to be seen in a presentation room.

This is a good example of powershell being embedded in another application.

Now the question is how did I find out about this property?

First I started up the ISE

Then I wanted to find out what variables existed.

That required querying the variables virtual drive:

However I can’t remember the name of this drive.

So the starting point was:


This returned a list that looks like:

Name Provider Root
Alias Microsoft.PowerShell.Core\Alias
C Microsoft.PowerShell.Core\FileSystem C:\
Cert Microsoft.PowerShell.Security\Certificate \
D Microsoft.PowerShell.Core\FileSystem D:\
E Microsoft.PowerShell.Core\FileSystem E:\
Env Microsoft.PowerShell.Core\Environment
F Microsoft.PowerShell.Core\FileSystem F:\
Function Microsoft.PowerShell.Core\Function
HKCU Microsoft.PowerShell.Core\Registry HKEY_CURRENT_USER
HKLM Microsoft.PowerShell.Core\Registry HKEY_LOCAL_MACHINE
Variable Microsoft.PowerShell.Core\Variable
WSMan Microsoft.WSMan.Management\WSMan

From this I was able to identify the Variable PSDrive.

I was then able to change directory to the variable drive and then list the contents

cd variable:


This showed the following:

Name Value
$ dir
? True
^ dir
args System.Object[]
ConfirmPreference High
DebugPreference SilentlyContinue
Error System.Collections.ArrayList
ErrorActionPreference Continue
ErrorView NormalView
ExecutionContext System.Management.Automation.EngineIntrinsics
false False
FormatEnumerationLimit 4
HOME C:\Users\Chris
Host System.Management.Automation.Internal.Host.InternalHost
input System.Collections.ArrayList+ArrayListEnumeratorSimple
MaximumAliasCount 4096
MaximumDriveCount 4096
MaximumErrorCount 256
MaximumFunctionCount 4096
MaximumHistoryCount 4096
MaximumVariableCount 4096
my7digitalKey 7dvtxrfd7pm5
my7digitalsecret gek57mdmmqvk85cn
MyInvocation System.Management.Automation.InvocationInfo
NestedPromptLevel 0
OutputEncoding System.Text.SBCSCodePageEncoding
PID 26208
profile C:\Users\Chris\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.
ProgressPreference Continue
PSBoundParameters System.Management.Automation.PSBoundParametersDictionary
PSCulture en-GB
PSDefaultParameterValues System.Management.Automation.DefaultParameterDictionary
PSHOME C:\Windows\System32\WindowsPowerShell\v1.0
psISE Microsoft.PowerShell.Host.ISE.ObjectModelRoot
PSSessionApplicationName wsman
PSSessionOption System.Management.Automation.Remoting.PSSessionOption
PSUICulture en-US
psUnsupportedConsoleApplications Microsoft.PowerShell.Host.ISE.UICollection`1[Syste
PSVersionTable System.Management.Automation.PSVersionHashTable
PWD Variable:\
ShellId Microsoft.PowerShell
StackTrace at System.Management.Automation.Internal.PipelineProcessor.Synchronou
sExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, Co
mmandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] c
ommandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame
true True
VerbosePreference SilentlyContinue
WarningPreference Continue
WhatIfPreference False

From this the psISE looks to be the thing that I am looking for.

The next step is to inspect the object to see what I can find to use.

$psISE | gm

Name MemberType Definition
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
CurrentFile Property Microsoft.PowerShell.Host.ISE.ISEFile CurrentFile {get
CurrentPowerShellTab Property Microsoft.PowerShell.Host.ISE.PowerShellTab C
urrentPowerShellTab {get;}
CurrentVisibleHorizontalTool Property Microsoft.PowerShell.Host.ISE.ISEAddO
nTool CurrentVisibleHorizontalTool {get;}
CurrentVisibleVerticalTool Property Microsoft.PowerShell.Host.ISE.ISEAddOnT
ool CurrentVisibleVerticalTool {get;}
Options Property Microsoft.PowerShell.Host.ISE.ISEOptions Options {get;}
PowerShellTabs Property Microsoft.PowerShell.Host.ISE.PowerShellTabCollecti
on PowerShellTabs {get;}

Options look promising.

$psISE.Options | gm

Name MemberType Definition
PropertyChanged Event System.ComponentModel.PropertyChangedEventHandler PropertyChanged(System.Object, System.ComponentModel.PropertyChangedEventArgs)
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
RestoreDefaultConsoleTokenColors Method void RestoreDefaultConsoleTokenColors()
RestoreDefaults Method void RestoreDefaults()
RestoreDefaultTokenColors Method void RestoreDefaultTokenColors()
RestoreDefaultXmlTokenColors Method void RestoreDefaultXmlTokenColors()
ToString Method string ToString()
AutoSaveMinuteInterval Property int16 AutoSaveMinuteInterval {get;set;}
ConsolePaneBackgroundColor Property System.Windows.Media.Color ConsolePaneBackgroundColor {get;set;}
ConsolePaneForegroundColor Property System.Windows.Media.Color ConsolePaneForegroundColor {get;set;}
ConsolePaneTextBackgroundColor Property System.Windows.Media.Color ConsolePaneTextBackgroundColor {get;set;}
ConsoleTokenColors Property System.Collections.Generic.IDictionary[System.Management.Automation.PSTokenType,System.Windows.Media.Color] ConsoleTokenColors {get;}
DebugBackgroundColor Property System.Windows.Media.Color DebugBackgroundColor {get;set;}
DebugForegroundColor Property System.Windows.Media.Color DebugForegroundColor {get;set;}
DefaultOptions Property Microsoft.PowerShell.Host.ISE.ISEOptions DefaultOptions {get;}
ErrorBackgroundColor Property System.Windows.Media.Color ErrorBackgroundColor {get;set;}
ErrorForegroundColor Property System.Windows.Media.Color ErrorForegroundColor {get;set;}
FontName Property string FontName {get;set;}
FontSize Property int FontSize {get;set;}
IntellisenseTimeoutInSeconds Property int IntellisenseTimeoutInSeconds {get;set;}
MruCount Property int MruCount {get;set;}
ScriptPaneBackgroundColor Property System.Windows.Media.Color ScriptPaneBackgroundColor {get;set;}
ScriptPaneForegroundColor Property System.Windows.Media.Color ScriptPaneForegroundColor {get;set;}
SelectedScriptPaneState Property Microsoft.PowerShell.Host.ISE.SelectedScriptPaneState SelectedScriptPaneState {get;set;}
ShowDefaultSnippets Property bool ShowDefaultSnippets {get;set;}
ShowIntellisenseInConsolePane Property bool ShowIntellisenseInConsolePane {get;set;}
ShowIntellisenseInScriptPane Property bool ShowIntellisenseInScriptPane {get;set;}
ShowLineNumbers Property bool ShowLineNumbers {get;set;}
ShowOutlining Property bool ShowOutlining {get;set;}
ShowToolBar Property bool ShowToolBar {get;set;}
ShowWarningBeforeSavingOnRun Property bool ShowWarningBeforeSavingOnRun {get;set;}
ShowWarningForDuplicateFiles Property bool ShowWarningForDuplicateFiles {get;set;}
TokenColors Property System.Collections.Generic.IDictionary[System.Management.Automation.PSTokenType,System.Windows.Media.Color] TokenColors {get;}
UseEnterToSelectInConsolePaneIntellisense Property bool UseEnterToSelectInConsolePaneIntellisense {get;set;}
UseEnterToSelectInScriptPaneIntellisense Property bool UseEnterToSelectInScriptPaneIntellisense {get;set;}
UseLocalHelp Property bool UseLocalHelp {get;set;}
VerboseBackgroundColor Property System.Windows.Media.Color VerboseBackgroundColor {get;set;}
VerboseForegroundColor Property System.Windows.Media.Color VerboseForegroundColor {get;set;}
WarningBackgroundColor Property System.Windows.Media.Color WarningBackgroundColor {get;set;}
WarningForegroundColor Property System.Windows.Media.Color WarningForegroundColor {get;set;}
XmlTokenColors Property System.Collections.Generic.IDictionary[Microsoft.PowerShell.Host.ISE.PSXmlTokenType,System.Windows.Media.Color] XmlTokenColors {get;}
Zoom Property double Zoom {get;set;}

And here we find fontsize

This gives the command that I demonstrated at the start.

The following commands were used in the construction of this article:

get-psdrive | select Name,Provider,Root | ConvertTo-Html -Fragment
dir | select Name,Value | ConvertTo-Html -Fragment
$psISE.Options | gm | select Name, MemberType, Definition | convertto-html -Fragment | clip