Introduction

 Top Next

Here is a useful URL / link :-

www.powershell.org

*** WARNING *** Before we get into any interesting discussion, command running, or execution of scripts,

let me tell you that you can do virtually anything to the Windows 10 environment with PowerShell.

Yes, this means change settings and delete data of many sorts and types - CARE !?

For this reason you will see command-lets starting with 'Get-' used a lot for demonstration purposes.

These command lets (termed 'cmdlet's) simply find and report back existing data from the system (O/S),

which in mine and most guy's case is Windows 10.

So a simple example is "Get-Verb" as seen below :-

Yes, this command shown above is actually made up of one 'cmdlet' called "Get-Verb".

We should not do much damage running this command - so look out for quite a few more "Get-"s in these eNotes.

Most of the basic techniques and skills of PowerShell can be acquired and practised with such commands.

*** Note *** it seems great to be able to write and run a simple command to close an open instance of 'Notepad'.

However, it is not much more of a command to close down everything, including the PC itself ;-0((

Lets now move on and have some 'FUN' because using and learning PS5 is indeed good fun.

I thoroughly recommend that you make a Windows 10 virtual machine, and then do your PS learning from

the safer environment of the VM itself.

==============================================================================

Here is what Lee Holmes has to say by way of an introduction to his 'CookBook' :-

"Introduction :

Windows PowerShell promises to revolutionize the world of system management and

command-line shells. From its object-based pipelines to its administrator focus, and to its

enormous reach into other Microsoft management technologies, PowerShell drastically

improves the productivity of administrators and power users alike.

When you’re learning a new technology, it is natural to feel bewildered at first by all the

unfamiliar features and functionality. This perhaps rings especially true for users new

to Windows PowerShell because it may be their first experience with a fully featured

command-line shell. Or worse, they’ve heard stories of PowerShell’s fantastic integrated

scripting capabilities and fear being forced into a world of programming that they’ve

actively avoided until now.

Fortunately, these fears are entirely misguided; PowerShell is a shell that both grows with

you and grows on you."

========================================================================

Lee Holmes calls the following, the eight pillars of 'PS' :-

• PS works with standard Windows commands and applications.

You don’t have to throw away what you already know and use.

• 'PS' introduces a powerful new type of command.

'PS' commands (called cmdlets) share a common Verb-Noun syntax and offer many usability

improvements over standard commands.

• 'PS' understands objects.

Working directly with richly structured objects makes working with (and combining) 'PS'

commands immeasurably easier than working in the plain-text world of traditional shells.

• 'PS' caters to administrators.

Even with all its advances, 'PS' focuses strongly on its use as an interactive shell: the experience

of entering commands in a running 'PS' application.

• 'PS' supports discovery.

Using three simple commands, you can learn and discover almost anything 'PS' has to offer.

• 'PS' enables ubiquitous scripting.

With a fully fledged scripting language that works directly from the command line, 'PS' lets

you automate tasks with ease.

• 'PS' bridges many technologies.

By letting you work with .NET, COM, WMI, XML, and Active Directory, 'PS' makes working

with these previously isolated technologies easier than ever before.

• 'PS' simplifies management of data stores.

Through its provider model, 'PS' lets you manage data stores using the same techniques

you already use to manage files and folders.

..... I strongly suggest that you read the above eight pillar 'statements' two or three times.

Maybe even each day you are learning PS, at the start of the morning ;-0)

Good Luck.

========================================================================

PHH - 30th. October & December 22nd. 2015.


What is 'PowerShell'

 Top Previous Next

PowerShell is an in-built software tool for all modern Windows operating systems, both Server

and stand alone.

It really is a tool for administrators who manage Windows servers, but it is there for all of us to use - as

a 'layer' beneath all modern Windows based O/S.

So PS5 (PowerShell version 5) is in 'Windows 10' and Server 2012 R2 (and beyond).

It really is the product of earlier Microsoft work on 'Monad', which in turn was a huge development

from the earlier MS-DOS command driven text based management environment.

To meet the needs of modern ICT guys Monad and then PowerShell had to be 'Object Based',

which it is, very much so. And as a consequence .NET guys will take to it easily.

So administrators management software tool it is, but also it supports a flexible 'Scripting' platform

which allows text lines to be written which looks very much like C# code and using the .NET framework.

Although we can write nice Scripts, we MUST NOT forget that MS has built into PS5 a very convenient

and powerful command driven syntax. We can tap into this 'command way' of doing stuff even in our Scripts.

We have the best of both worlds, as these two apparently different aspects are totally compatible and

can be mixed together.

Before we move on, try this quote from :-

http://blogs.technet.com/b/heyscriptingguy/archive/2015/01/02/what-is-powershell.aspx

=========================================================================================================================================

Windows PowerShell is both interactive and script :

One thing that confuses people when talking about Windows PowerShell is that they see what looks like a big blue

Command Prompt window, and they think “Oh, that is Windows PowerShell.”

Then at other times, they see what looks like a really complicated bunch of code, and they think, “Oh, that is

Windows PowerShell.”

Of course, one of the great things about Windows PowerShell is that it is interactive. We can easily type a short

command, and retrieve tons of information.

A sort of "beast with two heads".

=====================================================================================================================================

[ In many ways the 'learning curve' is quite shallow - a nice change from the world of MVVM and data binding, as well

as inversion of control etc,. etc.. ]

======================================================================

Yes, I have certainly found the above sentiment to be true in my case ;-0)

The following is also true :-

==============================================================================================================================

Finally try this :-

https://technet.microsoft.com/en-us/library/dd347627.aspx

And most importantly the following :-

============================================================================================================================

Time to move on, we have lots to think about !

See you in the next sub-section ........................

PHH - 30th. October 2015.


Why use 'PowerShell'

My Personal opinion :

After doing a lot of research, and trying out many commands and writing a good few Scripts, I do not

believe that any serious professional developer has any choice at all - its a MUST for us to know

and use PowerShell.

If you go near the standard Windows 'Command window' then STOP, and use PowerShell instead.

You may even become a better .NET coder after studying PowerShell 5.0.

=====================================================================

http://blogs.technet.com/b/heyscriptingguy/archive/2015/01/02/what-is-powershell.aspx

========================================================================================================================

==============================================================================

http://www.techrepublic.com/blog/10-things/10-cool-things-you-can-do-with-windows-powershell/

===========================================================================================================================

*** WARNING *** This article below is over 6 (six) years old - there is even MORE reason now than ever !!!

===========================================================================================

And before we move on ...........................

Objects - Good for All of us :

If you remember one thing about PS5 it should be that it is totally based on 'Objects'.

And that .NET programmers can bring over a whole bunch of skills from the .NET framework, and use

them directly in PS5'

Study this below :-

============================================================================================================================

All good so far - so what are we waiting for ? Lets get cracking and learn some PowerShell.

See you in the next sub-section ............................................

PHH - 30th. October 2015.


General 'Overview'

Here is how things look to me after spending a good 'solid' four weeks at learning PowerShell.

On the sort of 'programming' side of things :-

- we need to get skilled at using 'Commands'

- we need to become familiar with as many 'cmdlets' as possible.

- we need to become masters of the 'Pipeline' approach

- we need to become skilled at writing and running script code

- we need to incorporate Commanding skills with the script design and creation process

- we need to be able to design / create, as well as use 'Functions'

- we need to get heavily into objects as well as collections

- we need to be good at using parameters

- we need to start using Regular Expressions ('RegExes')

- we need to become good at using the PS in-built Help system

On the 'software tools' side of things :-

- we need to be able to survive while using the console pane, if needs be

- we need to get to grips with 'Windows PowerShell ISE' or preferably 'PowerShellPlus'

- the above entails using and creating snippets

- we need to be able to write advanced functions and our own 'Get-Commands'

- we need to manage our scripts in a clear way

- we need to join or access an active forum so we keep in touch with developments

- we need to tap into the GUI help - web or CHM file, in the best way possible.

On the 'system management' side of things :-

- it would be desirable to create and use a Virtual Machine for learning purposes

- we need to get into using Profiles and Modules - and maybe Templates too.

- we need to be able to manage debugging and error handling

- we should be able to employ some logging techniques

PHH - 24th. November 2015.


a Personal view of 'things' !

My Personal opinion :

After doing a lot of research, and trying our many commands and writing a good few Scripts, I do not

believe that any serious professional developer has any choice at all - its a MUST.

If you go near the Command window then STOP and use PowerShell instead.

Don't use this :-

Use this instead (perhaps) :-

You may even become a better .NET coder after studying PowerShell 5.0.

=====================================================================

The above short section I wrote for the previous sub-section.

Here I will expand my thoughts on what I think, in an attempt to help you move forward with PS5.

Forget the bog standard PowerShell 'blue' window if at all possible (see above).

Most guys who are NOT system administrators (like you and me) will be well advised to use the 'ISE'

tool which Microsoft builds into Windows 10. See below :-

In fact you will be well advised to download a FREE copy of 'PowerShellPlus' and use that as your preferred

GUI software tool, for commanding and script development.

PSP has a well developed set of features and functions, as well as a good Help file too. Checkout below :-

[ .. Yes! - it does look a lot like Visual Studio .. ;-0) .. ]

Don't be afraid to use the advanced features of the editors in PSP and ISE - 'drag and drop' your code lines

and inserted code snippets. Use the Windows modifier key (Ctrl) to make this into a drag and copy, as

opposed to a move.

======================================================================

Use the 'surround by' context menu options in PSP, these termed 'Comments / Selection' - these things

are all very productive when used right by us.

=========================================================================

Yes, this is all very nice - so why not go and visit the sub-section further down this chapter on PSP itself

and get a download installed and ready to go.

The more we use PSP the better we will get at it, as well as learning more features and facilities that

it has to offer.

See you in the next sub-section ........................

PHH - 30th. October & 24th November 2015.


Learning and reference materials

Here is something most interesting and stimulating, that I found in Brian Cafferky's text :-

========================================================================================

Think hard on this and then go and 'kindle' yourself !!

===========================================================================

We have plenty of material out there to support us with learning and using PowerShell.

However, do be aware that lots of it can be from years ago, and even well recognised 'good' books

and eBooks can be at least two versions of PS behind. A lot still works, but the new features are

missing.

This is why I recommend you try purchasing the recent edition from Ed Wilson, the 'Microsoft Script Guy',

as he likes to be known, and calls himself by this title.

In fact I recommend you get all three of the eBooks I have purchased - these are seen below :-

http://ewblog.edwilson.com/

http://www.edwilson.com/Default.aspx

==============================================================================

Lets move on to some other material I have used in the past and am still referring to regularly at the moment.

=================================================================================

Lee Holmes is author of the eBook I am following as part of my learning regime for PowerShell 5.0.

Here is a very useful link which has opened up the scripting possibilities for me as a .NET guy.

ttp://www.leeholmes.com/blog/2006/08/18/creating-generic-types-in-powershell/

==========================================================================================================================

I have been using and referencing the following eBook for quite some time - it can prove VERY useful.

However, I found that it complemented other texts I also used a lot, form Jones & Hicks, and Ed Wilson too.

================================================================================

=====================================================================

===================================================================================================

I have personally used this PS3 eBook a LOT, by Jones and Hicks.

With all three books (Wilson, Holmes, Jones & Hicks) I found that each had something different, or extra to add.

You can't do it all (learn a lot of PS5) by just Googling and the likes, even though that can provide

answers and results under certain circumstances.

================================================================================

=================================================================

========================================================================================================================

=========================================================================================================================

The next entry seems to be a great addition to this chapter's sub-folder, as it deals specifically with data and SQL 'stuff'.

=============================================================================================================

==========================================================================================

*** NOTE *** I have purchased all four of the above eBooks and am using them regularly.

PHH - 30th. October & 17th. November 2015.


Continued and Community Support

Guys to be aware of :-

Ed Wilson - Microsoft Scripting Guy

Lee Holmes

Don Jones,

Jeffery D. Hicks

http://www.leeholmes.com/blog/

http://powershell.org/wp/tag/lee-holmes/

http://social.technet.microsoft.com/wiki/contents/articles/183.windows-powershell-survival-guide.aspx

====================================================================================================

http://www.microsoft.com/en-gb/download/details.aspx?id=7097

Strange format the result of the above link - WORD document !?

https://technet.microsoft.com/en-us/library/cc196356.aspx

===========================================================================================================================================================

PHH - 30th. October 2015.


My software platform used here

Throughout the creation and development of these eNotes about PowerShell 5 I will use the following

software platform.

The main operating system will be Windows 10, however I am using the Insider builds from Microsoft as

they are released. Currently I am using build 10565 but there is likely to be another new release soon.

Here is my main monitor screen, bottom RHS (right hand side) :-

Since 'PowerShell' is in many ways a simple thing to use, we do not need to know much more of what

my desktop development platform looks like.

I have to say it is rather refreshing to be able to do uncomplicated stuff again after quite a few years of

complexity with SQL Server, Visual Studio, MVVM development patterns, and the likes.

After using the above build I had an update and then it went to a higher number build.

Then yesterday (Nov. 7th. 2015) things changed again ......................

Oh! - things change fast these days :-

Now I have no build number, even though the update came from the 'Insider' platform.

Help Viewer 2.2 :

I use Help Viewer from Microsoft a lot in my research and eNote creation.

Although some of us may know this through the use of Visual Studio 'Help', in fact it is

a stand alone application, and can be launched and run separately.

The image below was screen captured for a free standing instance I launch from the Taskbar.

Note below that the version is the current (latest) one of '2.2'.

====================================================================================

And here is my PC platform set-up as far as the Taskbar is concerned :-

You can find out more about accessing Help Viewer in the Appendix section for 'Tips and Tricks'.

PHH - 30th. October 2015.


How do YOU start ?

Before we can start to type in and use either 'Commands' or 'Scripts' we need to access the software

tools from within "Windows 10" and bring them to the 'TaskBar' and 'Start Screen', for easy regular use

as we do our learning.

First of all, lets use the Windows key and icon area to find out what is available when we type 'powershell'

in the search box - see below for the on-screen Windows icon :-

If you prefer type the Windows key on the keyboard and just immediately type 'powershell' to bring

up the following screen details - check these out fully :-

==============================================================

Bring up the PowerShell desktop apps in a way similar to that shown in the images displayed here.

You need to find and 'pin' both 'PowerShell' and 'PowerShell ISE'. I suggest you pin to both Start and Taskbar.

Use x64 bit varieties if your system is x64 'Windows 10'.

For the moment ignore below the entry for the 'Plus' edition, this is a download, and will be discussed later.

Here is what I see :-

========================================================

How then guys, if you do things right and get your pinning correct, you will then

be able to see things on your desktop like the images below of mine :-

In fact I use the next Taskbar icon the most, simply because it allows me to launch both

varieties of PowerShell (PS).

Also I suggest that you take the advice that I read somewhere 'quality' and always launch your

PS console or GUI 'ISE' in administrator mode.

*** Top Tip *** Always use Administrator mode !!!

If you like you can also set the Properties pane and tabs so that even the ordinary mode icon

entry starts in Admin mode.

Follow this :-

And under the Advanced option on the Shortcut tab see this below :-

And then obviously we need to check the 'Run as Administrator' check-box.

Here is how it should look :-

==============================================================

Okay then folks, if we do things right we can then launch multiples instances of both PS and PS 'ISE'.

The top Title bar tells us clearly if we are in Admin mode - check this more complex screen capture of my system :-

I have four instances of ISE open and two of the PS console. Two each of the 'ISE' are admin and normal modes.

Here below is a better (larger / clearer) view of the ISE instances (one each of ISE and console) :-

And now we see a closer-up image of the console window.

The PS console is often called a window, and sometimes a pane. As in results pane. We need to get

used to a variety of names for these PS working instances.

Note that blue panes can always be used for both typing input commands as well as seeing output

results and data. This is true of the blue pane within ISE as well.

Here is the command console :-

Lets see what our two experts have to say - well two of the four we have so far indicated or named :-

"Jones & Hicks" say :-

===========================================================================================================

What version are we using ? :-

$PSVersionTable is a system variable, and we will explore these more later in the eNotes.

Appendix 'S' is the place to look.

PHH - 30th. October 2015.


What to use - Console or 'ISE' ?

Guys, we are lucky, we have a choice of software tools, as long as the O/S platform we are using

allows us to be visual and use the ISE version of the boring old Console window.

======================================================================

For the vast majority of guys, using PS5 will be about running commands, and command line utilities.

This is what it is to many folk, NOT scripting or programming.

[ Please note, that even though we start by using single line 'Commands' we can still use the GUI interface

version of the Console. ]

However, I would like to get myself to be able to make simpler 'script' files as I have done 'Batch'

files in the past - and explore what possibilities may exist for running Scripts through .NET apps,

if indeed security issues and settings allow such things these days.

For scripting use the ISE if it is available. I will use it all of the time, even when just doing Commands.

Here is the Console window at the start of a session :-

And now we see the alternative tool, the ISE window app - check below :-

Notice in the two images shown above, that both tools are opened (launched) in Administrator mode. To check

this for yourself, look at the Title Bar at very top left of window.

WARNING - other information sources !? :

Please be aware that you may read in eBooks and web articles about the ISE of PowerShell being

written in WPF and using WPF technology - BUT - in a test I have just carried out this does not

seem to be the case.

I have an applet called 'Snoop' which finds and displays any window in any running app which is

a WPF window.

=====================================================================================================

http://snoopwpf.codeplex.com/

How to get Snoop - try the above URL / link.

======================================================================================================================================

After an easy install we see this :-

======================================================================

And then in the Windows 10 Start we get the following :-

==============================================================

====================================================================================================

Okay then folks lets move on, and return to learning about PowerShell 5 and the Console and ISE.

==================================================================================

Lets do some interesting experimentation :

If I open Visual Studio 2012, as well as my very useful 'Snagit' screen capture app, I see the following

details with the SNOOP information bar moved (or slid) over the Task manager - check this :-

===========================================================================================================================================

The other bit of information you need, to make sense of the above image and what I am talking of,

is the fact that I also have open the x64 version of 'PowerShell ISE'.

Even after a refresh I can't get the combo / drop list to show any entries relating to PS5 ISE or its sub-windows.

So either someone out there is misinformed, or that Snoop 2.7.1 no longer does what I thought it did 100%

accurately. However, it picks up the latest /Snagit/ and VS bits too !!??

Below is an image of 'Snoop' working on 'Snagit' :-

PHH - 30th. October 2015.


the Console

With most programming languages, you sit down in front of a text editor (even if it’s Windows Notepad)

and type a series of keywords to form a script.

You save that script in a file, and perhaps double-click it to test it out.

PowerShell can work like that, but that’s not necessarily the main usage pattern for PowerShell,

particularly when you’re getting started.

With PowerShell, you type a command, add a few parameters to customize the command’s behavior,

hit Return, and immediately see your results.

PHH - 30th. October 2015.


the GUI tool called ISE

=====================================================================================================================================================================

=================================================================================================================

https://technet.microsoft.com/library/dd819514.aspx

======================================================================================================================================================================================

PHH - 30th. October 2015.


PowerShell 'Plus'

' PSP ' - "PowerShell Plus" :

Okay then guys, we are about to have a look at a software tool from 'IDERA' - that's correct, a

tool from someone other than Microsoft.

So far PS console and PS 'ISE' have been discussed and they can certainly get any folk off to a

really good start with both learning and using PowerShell.

In many ways the Microsoft tools are charming, a breath of fresh air, simply because of their simplicity.

However, for some other guys who consider themselves as professionals, and who also may need to

work at a level where productivity matters a lot, then the more complex tool called "PowerShell Plus"

is a must-have. I think I just got and downloaded version '5.0'.

Unfortunately for some (and there are a few guys out there - I will not name names!), there are many

similarities between PSP and Visual Studio from Microsoft.

If you are a VS 'hater' then stick with ISE from Microsoft, if you have no GUI support on your PC platform

then stick with PS console, BUT, if you are a VS lover/liker, and you enjoy using quality software, then

go for getting a free download and use PSP.

After using the web to register for a free download you will get something like this in your email box :-

===============================================================================================

And here below is a link which may prove useful / helpful to you :-

http://community.idera.com/blog/idera/powershell-plus-5-0-is-now-available-2/

Here are some image details to encourage you ;-0)

========================================================================================================================

https://www.idera.com/productssolutions/freetools/powershellplus

===================================================================================================================================================

===================================================================================================================================

===========================================================

If you do everything right as far as the download goes, then you will eventually launch the tool and see this shown below :-

Yes, its quite a comprehensive 'shell' or IDE - " Integrated Development Environment ".

We need to look separately at some of the features within the environment.

I suspect that I will get to like this a lot, and many of you guys will as well.

See you in the next sub-section ...................

PHH - 6th. & 21st. November 2015.


Quick Click Library

====================================================================

PHH - 21st. November 2015.


System Explorer - My Computer ...

========================================================================================================

=======================================================================================================

=============================================================

==========================================================================

Detach - Free Floating :-

=================================================================================================

PHH - 21st. November 2015.


Floating Panes

*** BEWARE ***

If you un-dock panes and leave them floating, and then close down the PSP application, then

the next time you launch PSP these panes appear exactly where you left them - floating away from the

main shell.

Do not panic and think that you have lost part of the IDE ;-)

============================================================================

==============================================================================

PHH - 21st. November 2015.


Main Tabs

PHH - 21st. November 2015.


using the Console pane

PHH - 21st. November 2015.


using the Script editor

PHH - 21st. November 2015.


Running a command / set /script

=======================================================================================================================================================

PHH - 23rd. November 2015.


Forums and Support

===============================================

https://www.idera.com/productssolutions/freetools?utm_source=psplus&utm_medium=inproduct&utm_campaign=ftcategory&utm_content=btn

PHH - 21st. November 2015.


Getting HELP !

Be fully aware that there is a lot of information available in the PSP pane options as well as the Help we have

from the built in help file.

The CHM help file means we do not need internet access while using it.

Note below the little blue/white icon for this option to bring up the Help stand alone screen.

=================================================

===========================================================================================================================

PHH - 21st. November 2015.


Execution Policies - What we need to know

Profiles and Policies (Execution) :

There are some simple and obvious facts to take into account. This is all about security, and system

safety as such.

Because 'damage' can be done by executing PS scripts, we have a system 'way' or 'approach' to

allowing users to be able to run / execute scripts, or not !

And please remember that great damage can be done with even simple scripts. After all, PowerShell is

designed for administrators to be able to do anything at an O/S level. And from one PC or workstation

to another on the network, so 'remote damage' can be done if not prevented.

If you, as a user, have the correct user 'rights' then your system will be set to allow you to do so (Run

scripts). If not then you can't - as simple as that !

=======================================================================

Ed Wilson gives us some tips in his very useful eBook :-

A Windows PowerShell profile is a PS5 script that runs each time Windows PowerShell starts.

Windows 'PowerShell' does not enable script support by default.

In a network situation, the PS script execution policy might be determined by your network administrator via Group Policy.

[ Yes - you may have your hands tied ! ]

In a workgroup, or at home, the execution policy is not determined via Group Policy.

===========================================================================

Okay then folks lets give something a try - see below :-

*** NOTE ***

In order to learn as much PS5 as possible, get yourself a VM (virtual machine) on your own local PC

or desktop. Once you get experienced then move towards your own PC operating system, and also those

on other network PCs and devices.

Lets move on a pace or two .....

Try looking at this link :-

http://www.techrepublic.com/blog/10-things/10-powershell-commands-every-windows-admin-should-know/

And here below are a few useful excerpts for us to study and think about :-

=================================================================================================

===============================================================================================

PHH - 11th. November 2015.


Chapter 0 - Some basics and getting started

By the end of this first chapter - called chapter '0' (zero) to honour Don Caton - you will be able to

understand the following input command line and what it does :-

[ .. note that we are only seeing the first printer details - there is more .. ]

And as well as understanding the above sample /example, you will know how and why the following

command works, and what the new window is ;-0)

Study this carefully :-

Here are the results of the above command being run in the console pane :-

=========================================================================================================================================

Notice that the title bar holds the command which generated the 'GridView' - see above and below :-

======================================================================================================================================================

Yes, we have used four command-lets in the one command line at the console prompt.

Enough for now, lets move on to the chapter sub-sections where we will learn a lot more.

See you there ..........................

PHH - 30th. October & 24th. November 2015.


What is a Command ?

*** REMEMBER *** The output of a Command is an 'object' .

=========================================================================

By the word 'Command' we tend to mean the line of text which is typed into the console pane at the

cursor.

This command is generally run when we press enter - although there are some special exceptions.

[ .. see the child section from here to find out about command line splitting .. ]

So here is a simple command, they don't get a lot simpler than this ;-0)

The final character is the cursor and not a 'pipe' character - possibly because I was trying out the

editor in 'PowerShellPlus 5.0'.

Commands are also what scripts are generally made up from, one after another.

In Scripts, the Commands are in and around code structures - more on these later.

When we are using a more complex PS window, then typed commands need to be 'Run' and the

pressing of 'Enter' is not as in the simpler PS command type window pane.

As you can imagine there are many rules about what can and what can't be typed at the Command

prompt in the editor - and even editors vary in their ability to accept typed text lines !!

Lets move on a step or two ..................

=================================================================

In your eBook by Jones and Hicks, consult chapter 4 section 2 to see the topic of "Anatomy of a Command".

This section refers to the modern 'cmd-let' (or 'cmdlet') options, of which there are now about 2,200 or more.

[ .. 564 with 'Get-xxxx' names]

It is best for us if we forget the older DOS 'stuff' and learn how to do everything the PS5 way.

Below is the 'anatomy' diagram which they suggest we work with :-

====================================================================================

Okay then folks, let us try to do something really simple.

Let us try to run a 'cmdlet' command with no other parameters or inputs - see below :-

=======================================================================================================

Yes, all we have done is type the 'verb-noun' title of the cmdlet, and this is :- 'Get-PrinterDriver'.

We can use the GUI of the ISE to see that the module name is "PrintManagement" - as shown below :-

===============================================

If we use the GUI further we see that the parameters are just a few in number.

Checkout the next image for full details :-

====================================================

Applying a little 'piping' to the above we can select out our own property (or column) for the

found data.

Checkout the use of 'select' as a useful tool :-

However, we can select the properties we wish, and also the order in which they are displayed.

Lets try just two - as seen below :-

And now run the command line to get the following :-

So far so good .... now lets move on a step or two .........

How about trying to put two commands together, the output object from the first, going into the next as an

'input' object - check this out below :-

====================================================================

Now we can use this very same example as a way of scripting some code in the script editor,

and see how a .NET guy like myself may code the script :-

==================================================================================================

Please realise that the floating 'window' which is the 'GridView' is produced by both the console command

line as well as when we run the script lines.

Although writing and using command lines is both and efficient way to do things and a very concise way

to type/write effective input, it can lack a lot of 'obvious' meaning to the casual reader.

When it comes down to it, understanding someone else's long command line is going to be usually more

difficult than reading and understanding a few well written script code lines.

We can, and should, create script as well as we do clear C# code.

Time to move on I feel !

See you in the next sub-section ...................................

PHH - 30th. October & 24th. November 2015.


Splitting command lines

This seems a bit of a tricky topic and also one which seems to vary on which editor and/or

console pane we are using.

I say this because the nice 'free' app called 'PowerShellPlus 5.0' is different to the MS standard tools.

We just need to be a bit flexible in our approach ;-0)

It would appear that using piping characters as a guide we can split lines in our scripts okay.

Look carefully at the following image :-

This above both looks good and runs well - we are using the Microsoft ISE tool.

If we use the MS PS5 console instead of the ISE tool, we can do the following :-

So this is nice, but when we try to do the very same thing in the blue results pane, which seems

to double up as a input console screen, we get 'red' grief - check below :-

This is useful to know,

However, in the slightly more complex IDE from 'Idera' - the folks who created 'PowerShellPlus 5.0' - we see

the following results - check this out below :-

Okay then - don't get confused, and don't give up.

The morale to this story is "Know thy Editor", and inside out as well !

I strongly suggest you spend some time getting to know all the ins-and-out, or wrinkles, of your

chosen editor and development environment.

Lets move on a pace or two ................

Another way to 'Split' up lines into shorter ones :

Before we enter into any discussion of what is going on, and how to do this alternative splitting,

lets take a look at some commands running in the PowerShell console window - check these out :-

Yes, we seem to have done something which we thought we knew would fail, or not work.

However, we need look a lot closer to the input text lines.

Lets try and magnify the command section to see what is really there - study the following :-

In the larger image above look at the ends of the top three lines of text.

There is a small character at the very ends of the lines and it looks like this ' ` ' if we enlarge it to twice

the font we are using for this body text I am writing.

It is called a 'backtick' said "back tick", and it is the escape character for PowerShell.

Jones and Hicks have this to say about escaping and "backticks" :-

.... "When you see the backtick in a code listing, type it exactly as is. Furthermore, when it

appears at the end of a line—as in the preceding example—make sure that it’s the very last

character on that line. If you allow any spaces or tabs to appear after it, the "backtick" won’t

work correctly, and neither will the code example." ............

And this is also their advice :-

=========================================================================================================

Actually, I thoroughly recommend that you purchase yourself a copy of their eBook - see the Introduction section

for details. It has helped me a lot while getting into PowerShell.

So we can use the escape character to split the line as long as it is the last character in the line - before the

carriage return character that is.

** Note *** this behaviour may also depend on your editor / console screen.

Moving on ............

Lets see how the scripting pane operates in ISE when it comes to the escape char and line splitting.

Take a careful look at the following image to see something new - yes, learning again ;-0)

Okay then guys, above we see what we may expect, as long as our escape 'backtick's are immediately

before the 'enter' or 'Carriage return' characters.

However, we have also included an extra one to what we used earlier, and now on line 4 we are

splitting up a set / group of properties.

It would seem that we can place the escape char anywhere in our command as long as it has no trailing

spaces (or other).

Lets go a little crazy ............... "Splitting until it hurts !? "

Study the next image and all its finer details :-

We can see that the the chopped up script stills work correctly. However, there is at least one

thing we need to know and apply to get this approach to work for us.

That is we MUST include a space character before the backtick in this example - see below :-

The other thing is to realise that we can't place an escape character anywhere, only some places,

those where it makes more sense.

For example we can't split up 'Get' as seen below :-

Now then finally on this topic for the moment, lets see if this works in the MS console pane.

Here is the result :-

Okay then, so if we are careful, and know our IDE / editor behaviour, then we have

enough control to split command lines so that we do NOT have to have great long and awkward ones.

Lets move on, ............ see you in the next sub-section.

PHH - 7th. November 2015.


Commands within the Command !?

If we think of a line of text type at the cursor in the PS5 console pane, then we can have parts

of this which are 'smaller commands' these are called command-lets of 'cmdlets' for short.

If we take a VERY simple (and short) command line like that seen below :-

then the whole command is actually one of these 'cmdlets'.

So if "Get-Date" is a command-let, then how many of these 'cmdlets' are there for us to use ?

Well let us try and answer this question for ourselves - using PowerShell.

We need to realise that commands found by "Get-Command" are not all 'cmdlets'.

Let us do some exploring and experimenting, on our way to learning some PS5 scripting.

If we use 'Get-Command' then we get a huge list of results - not all of type 'cmdlet' :-

How many ? Well once again PS5 comes to our rescue - try this out :-

[ .. *** NOTE *** line 5 should read 'Commands' and not 'cmdlets' !! .. ]

Yes, a long list of 2,227 item lines.

Now of these we have a sub-set, or sub-group, which ate those which start with 'Get' (remember verb noun for

cmdlet names) - "action - what" !

Let us add more detail to our input main command - check this out :-

So basically, we have 310 'Get' command-lets for us to use. Lets list a few :-

and then a few more at the bottom of the list :-

Okay then, so far so good !

Now that we know we have 310 'Get-' cmdlets - what do they basically 'do for us' ?

It would appear that all of them on some way of another retrieve data / information for us.

Some will get a single data item (like 'Get-Date' above) and many will get a few or many items

which are returned as a collection.

Obviously, 'Get-Command' returns a collection for us!

From a quick manual search through the results in the blue console pane, we seem to have

'CommandType' values of :-

- Alias,

- Function,

- Filter,

- Cmdlet,

- Workflow

It would be nice if we could write our own script to do this - watch this space ;-0)

We would like to know the different 'CommandType's and how many of each as well.

Here is a good start - check the details fully, and carefully :-

From the final concatenated string we should be able to create a String array of 'CommandType's.

And finally we have a simple script which does the basics of what we are after - even though it can

be tidied and improved etc., etc..

Check these details - the top 'foreach' has been collapsed as it has not changed :-

This is probably enough for the moment, till we get some more general experience.

The next thing to do is find the 'verbs' for the 'cmdlets' set - some manually found verbs are :-

- Add,

- Clear,

- Debug,

- Enable,

- Get,

- Format,

etc.,

etc.

If you are new to PowerShell you may with to go straight to the next super-section of this chapter 0, otherwise

visit the child section to see how to find 'cmdlets' with various 'verbs'.

See you in either place ............

PHH - 7th. November 2015.


Some simple first examples

The best way to learn about commands, or in particular 'cmdlets' or command-lets, is to use them.

If we get used to trying out some simple cmdlets first, then we can get experienced later with the more

complex cmdlets.

Remember there are over two thousand of these and so we need to be patient with our learning ;-0)

==========================================================================

Let us do some simple exploring into the use of one or two related command-lets.

For our first command lets use "Get-Clipboard" - but first we need to see what scripting I was doing

just prior to this latest experiment.

Below you see that I have code from highlighting and then dragging and dropping line 6 into

line 7 of the script section.

Study this small detail - see below :-

Now let us try a very simple command line which is made up from one cmdlet and no input parameters.

Here is the 'Get' form of what is available :-

Note the detail held within the Clipboard - yes the same as line 6 without the # comment character.

Now let us augment the simple test to three lines, where we both 'Get' and 'Set' the Clipboard.

Checkout these details :-

In the above image we have two executions of the same code - and as you can clearly see the

original line 6 content is clear out, or over-written.

Lets see how many cmdlets there are within the whole command-let bunch - check below :-

Yes, only the two we have already met and used.

And also shown below are the version and source details for these two cmdlets :-

Lets move on ...........................

Exploring what the Clipboard can hold :

Okay then guys, it is easy to see and test how the Clipboard can accept and return a simple string, or short text message.

However, if all things "PowerShell and supporting system" are object based, then we ought to be able to do more, and better, than this ;-0)

What can we do with 'Objects', and complex objects ?

Lets try to store, then retrieve an object - we can start with an array of items, checkout carefully the following details :-

Yes, we have an array of eleven items which is returned by the Get-Printer cmdlet.

Checkout, and follow through, the script which generates the console results display.

Now lets see if we can place more in the Clipboard - a bigger object, a larger array of items ?

Lets see what happens when we try ALL of the command-lets :-

Yep! - all 22-8 of them - and these end in what is shown below :-

PHH - 28th. December 2015.


Experimenting with the 'Environment'

Okay folks, lets do some exploring and experimenting. During which we can examine the use

of a couple of STATIC methods, from within the .NET framework.

Only by fully exploring and experimenting will we gain a fuller, and deeper understanding of the

PowerShell facilities, and not just the .NET aspects of PS5..

Let us start by trying out three similar command lines, each with a different input parameter.

Checkout these lines :-

[ .. below we are calling three STATIC methods .. ]

The full Namespace referred to is "System.Environment" - we will see this used in full later.

If we happen to know the text string to use as input, then we can find out the folder path for that special folder.

We may be well acquainted with some of those special folders available - some of which are shown below :-

========================================================================================================================

Just about everyone is aware of 'Music', 'Pictures' and 'Desktop' in Windows - if not a few more.

Here is a full list - note that at a level below "File Explorer", 'My' is added as a prefix to these folder names - checkout

MyMusic, MyPictures, MyDocuments, MyComputer, and a few more :-

==================================================================

=============================================================================

================================================================================

PHH - 29th. December 2015.


Simple examples - running 'Commands'

Remember, the way to unleash the full power and flexibility of the PowerShell system is by the

correct and clever use of the command facilities.

Just like a great SQL guy is brilliant at using the SELECT statement, PS5 guys need to be

equally brilliant designing and running Commands.

Even if we .NET coder guys like the idea of creating and running scripts, we are still WELL advised

to incorporate into our scripting the more advanced ways of using Commands.

MANY of the cmdlets (command lets) - and there are a large number - 'do work' for us such that we

need not do our own scripting versions, or interpretations. Don't reinvent the wheel!

Lets get the most from the Commands available to us - both at the command prompt as well as

in our scripts.

What do we Mean by Commands ? :

After having worked on PS5 for many weeks, and having read a fair sample of articles on the web, as

well as eBook content, it would seem to me that we need to be flexible in how we interpret or translate

the words 'Command' and 'cmdlet'.

We could say that a command is what we type in, and run, at the prompt in the PS window.

So we can say that this is a Command - see below :-

Yes, we run it and get a result, as shown in the blue command / results pane.

However, 'get-command' or 'Get-Command' is itself called a 'cmdlet'.

So we can have a Command made up of one or more command-lets.

This means a more complex command can be made up of three command-lts as seen in the

next example of ours - check below :-

"Get-Command", "Where-Object", and "Out-Host" are all cmdlets.

So we could say we have a command line made up of three command-lets.

Here is an example command which proves the three are 'cmdlets' - check image below :-

And if we wish to split-up the command lines even further we can do the following :-

Notice in the above image the 'back-tick' character at the ends of lines 3 and 4. This is what is called the

escape character. Check out appendix 'E' for more on this.

Another Simple Example - History !? :

'History' is all the commands run in one session of the PS window being open and in use.

This works equally for ISE as well as the console prompt pane.

A new session starts when an instance of either of these is created / run.

Here is the cmdlet in the returned list :-

Lets try a simple command involving History on the current session I have open.

Yes, I have obviously run 81 different commands - some of which we have wrapped up

into a named script file. (Yes, even 'Untitledxxx' is a named script file.)

For our own benefit, this is one problem with this in as far as following through what

we did, and that is that script files can be edited / altered and we can't trace such

changes from one version to another, from this simple list.

So even one small cmdlet as a Command in itself, is quite useful to us.

Lets move on .....................

PHH - 30th. October & 20th. November 2015.


Using the 'Get' command lets

*** Rule of Thumb ***

Getting to know, and use well, the various 'cmdlets' (command lets) provided within PowerShell is

the secret to getting 'good' and proficient with PS5.

Designing and creating Command lines based on 'cmdlets' is as crucial to PS as being good at designing

and creating SELECT statements is for SQL Server proficiency ;-0)

'Get-' command lets provide us with data sets - usually / generally.

Because there are a LOT of cmdlets supplied within PS5 we need to be able to limit our searches for one

which may be suitable for our needs.

Let us write a short script to see the total number of command lets available to us :-

Yes, just as I thought, well over two thousand of them - a lot to get our heads around at once ;-)

However, in this sub-section we are only really focusing on those which start with the verb 'Get'.

So lets redesign our simple command script - check out this below :-

Oh! - that seems a lot better, we just have less than six hundred 'Get-' cmdlets. And of these 19 are

Alias entries, that means they are duplicates as far as functionality is concerned.

These Get- command lets are an easy way for us to ask the system to provided data for us in many different

ways. Yes, most 'Get-' commands lets will bring back data for us, and all should if it were available.

What I mean by this is that the cmdlet to tell us the Printers available will only return data if in fact there are

any printers registered with the O/S.

Most 'Get-' cmdlets will supply us with data.

Before we move on, let us take this opportunity to sort our results for 'Get-' cmdlets, as well as display

then on screen in a nice tidy GUI way - check this out below :-

You can see from the above screen output that it is difficult to show the multi-key sort in a way we can

visually check it out, simply because of the huge amount of data to display.

However, the highlighted row shows a source of 'Dism' and the CommandType 'A' then 'C' in order.

Lets move on ...............

Shall we see which cmdlets contain the character string 'sort' - see one solution in the following image :-

If we are to do something similar with a filtering command let, that of 'Where-Object' we would do this :-

Notice above that only two of the 'like' clauses actually produce results.

For any of you not familiar with using 'like' then check this out carefully too :-

Work out for yourselves why the third and fourth lines do not produce any results.

Let us move on and try some other commands ............

What about 'Select' ? :

In order to find out which commands start with the character string 'Select' lets try the simple way first :-

But if we use the more flexible (and complex) approach we can do this - checkout below :-

Remember, the 'Where-Object' is all about filtering - as in the Where clause in the SQL select statement.

We get the extra entries in the list because of ' *select* ' in place of ' select* '

Have a try yourself, and use some extra and different inputs.

Going a bit further .........................

Finding the Commands which deal with 'Object's :

So far we have used to good effect the cmdlet called "Where-Object", so it would be nice to know which

others there may be in the large set of cmdlets.

Try this for yourselves :-

Yes, above we see the SQL equivalents for Select, Where, Group and Sort - but there are some others

to which look quite useful.

In other sections of these eNote we will take a look at these others. For now we need to keep going ...........

Lets us see how we can pull results together from more than one command line.

Joining Results for one Output :

Lets try something simple as our first try at joining results output - check below :-

If we run all of the four command lines as a script, then we see what looks like one list.

However, rather than leaving control to the system / PS environment, .NET coder guys may

well prefer to take control in a short script. Checkout below :-

Yes, all of our results set are combined into one variable of our making.

This variable is then supplied down a 'Pipe' to the command let which creates a Grid View window pane.

And now lets get a bit more fancy and sort the lines by the 'Source' field (column) before we send the

results set to the 'Out-GridView' command let :-

The above results pane in the floating window should be relatively self-explanatory.

Time to move on to the next child sub-section where we will learn more interesting 'stuff'.

See you there ..................

PHH - 7th. & 20th. November 2015.


Why use 'Get-' cmdlets for learning ?

The answer to why we use 'Get-' command lets for learning purposes is VERY simple indeed.

They provide us with results sets, to then further process with suitable tools and commands.

Effectively they are "Read Only" as changes to the O/S and its settings are not made or done.

The 'action' or 'verb' of "Get-" does not mean change, add, insert, or remove - these things are

write actions, not fetching actions.

So we can play around with PowerShell and 'Get-'s without worry of damaging anything.

*** Warning *** there are some 'cmdlts' that we are well advised to stay completely clear of.

Be careful when following advice, and using scripts from web articles and blogs - even some

chapters in eBooks from genuine sources. I have personally come across one such entry in

the eBooks I am following, which said "do not do this on your P, or it will close itself down".

*** Recommendation *** Create and use a Windows 10 VM (virtual machine)

PHH - 20th. November 2015.


'cmdlets' from within PowerShellPlus Pro 5.0

Well folks, there may be over 2,200 command-lets and of these 564 are 'Get-' versions of the command

- BUT - in PSP (PowerShell PLUS Pro 5.0) we have a dedicated docking pane which makes life easy for

the developer / coder guy coming to PS use.

This specialised pane is named the "Quick Click Library" - we will see a lot more of this later.

Check out the following details :-

============================================================

The whole bunch of 'cmdlets' has been categorised and made easily accessible for us user guys.

The image above shows that we have open the 'Microsoft Hyper-V' bunch or set of cmdlets.

Below we can see the more general ones under "Getting Started" and 'My Computer', as well as

'My Desktop' and 'My Printer' etc., etc.. study the following image :-

========================================================

PHH - 21st. & 24th. November 2015.


Clipboard - 'Get' and 'Set' cmdlets

PHH - 27th. December 2015.


'Verbs' within 'cmdlets'

We need to find all the item entries in the results collection of 'cmdlet's from the 'Get-Command' cmdlet itself.

See below as a starting point for our scripting :-

We now need to be able to strip the verbs from the front of the Names of the commands.

First trials show this :-

And then tidying this script and making it more compact etc., we see this :-

So now we can incorporate this into a loop as we step through the collection items.

Here is an early script, with commented print out commands which were helpful for testing.

Check the full details :-

===========================================================================================================

And some of the results that were output :-

Then when we concatenate the unique 'verb' items we get the following :-

The full script and the results pane output are copied into the child section from here.

PHH - 7th. November 2015.


The easy way to see 'Verbs'

As with most things there is a 'cmdlet' which allows us to access the list of possible verbs.

Check this out below :-

*** Task ***

What we could do as a homework or learning task is take this as a data generating command, and

then write a script to display the verbs four at a time across the results console.

We will also need to format the verbs from a string point of view so they line up on the screen.

Now before we leave this sub-section let us put all the possible 'verbs' in an alphabetical list.

Checkout these details :-

And continuing to cut up the list into pieces we see the following details :-

Once again we could set ourselves a useful task of creating a function to accept the 'group' input

and then list the verbs by A-Z or Z-A in order of the 'Verb'.

PHH - 7th. & 24th. November 2015.


The easiest way to see 'Groups'

If we try to do the same for Group as we did for Verb in the cmdlets, then we hit a brick wall,

or dead end - check below :-

So we need to use some of our developing PS5 skills that are gradually building up.

Have a look at this next image - all details checked out :-

So we can have (I think) a bunch of Verbs for one Group and a bunch of Groups for each verb.

Here is an example for the verb 'Write' :-

So we must be able to easily create a function to accept a string verb value and then output the bunch

of command-lets.

PHH - 24th. November 2015.


Script & results

cd \

$myCmds = Get-Command |

Where-Object -filter {$_.CommandType -like 'Cmdlet'} |

sort Nam

$myCompVerb = ""

$myBuildString = ""

foreach($cmdlet in $myCmds)

{

  $name = $cmdlet.Name

  $verb = $name.substring(0, $name.IndexOf('-'))

  if($myCompVerb -ne $verb)

   {

      $verb

      $myCompVerb = $verb

      $myBuildString += $verb+","

   }

}

$myBuildString = $myBuildString.Substring(0,$myBuildString.Length-1)

$myVerbArray = $myBuildString.Split(',')

$myVerbArray

================================================================

PS C:\> C:\Users\the\Documents\PowerShell5\Untitled78.ps1

Add

Backup

Checkpoint

Clear

Compare

Complete

Confirm

Connect

ConvertFrom

Convert

ConvertTo

Convert

Copy

Debug

Decode

Disable

Disconnect

Dismount

Enable

Encode

Enter

Exit

Expand

Export

Find

ForEach

Format

Get

Grant

Group

Import

Initialize

Install

Invoke

Join

Limit

Measure

Merge

Mount

Move

New

Optimize

Out

Pop

Protect

Publish

Push

Read

Receive

Register

Remove

Rename

Repair

Reset

Resize

Resolve

Restart

Restore

Resume

Revoke

Save

Select

Send

Set

Show

Sort

Split

Start

Stop

Suspend

Switch

Tee

Test

Trace

Unblock

Undo

Uninstall

Unprotect

Unregister

Update

Use

Wait

Where

Write

Add

Backup

Checkpoint

Clear

Compare

Complete

Confirm

Connect

ConvertFrom

Convert

ConvertTo

Convert

Copy

Debug

Decode

Disable

Disconnect

Dismount

Enable

Encode

Enter

Exit

Expand

Export

Find

ForEach

Format

Get

Grant

Group

Import

Initialize

Install

Invoke

Join

Limit

Measure

Merge

Mount

Move

New

Optimize

Out

Pop

Protect

Publish

Push

Read

Receive

Register

Remove

Rename

Repair

Reset

Resize

Resolve

Restart

Restore

Resume

Revoke

Save

Select

Send

Set

Show

Sort

Split

Start

Stop

Suspend

Switch

Tee

Test

Trace

Unblock

Undo

Uninstall

Unprotect

Unregister

Update

Use

Wait

Where

Write

PS C:\>

PHH - 7th. November 2015.


Using the Console and/or the ISE

PHH - 31st. October 2015.


More about Commands - which, and History of use ...

History of a PowerShell session :

Or what did we do and in which order ?

We have a VERY useful (handy) cmdlet we can use to aid our memory - BUT - remember the 'History' is

volatile when the instances of console and ISE are individually closed.

So we have available to us just a current session History, unless of course we save the output in a file

before we close down the instance.

What is a Session ? :

While writing these eNotes and doing the research and testing, I usually have two PowerShell windows

open at once - one the command console and the other an ISE instance.

It is important to realise that each of these is quite independent in that they are unaware of what is

being typed and run as commands in the other one.

So any History of commands run is quite a separate list in one and the other.

Here is the history of the console window I have currently open on my desktop :-

Compare the individual lines with those of the image a couple above, for the ISE instance I have running.

Saving our Session History - making 'volatile' 'persistent' - "how to" :

PHH - 30th. October & 18th. November 2015.


Commands vs 'Scripting'

PHH - 30th. October 2015.


What is it that runs the commands and script ?

Early on in his eBook Ed Wilson has this to say :-

...... "Keep in mind that some cmdlets cannot implement some of these parameters.

However, if these parameters are used, they will be interpreted in the same manner for all cmdlets,

because the Windows PowerShell engine itself interprets the parameters. "

...............

So we can see that it is the PowerShell 'Engine' which runs a command and a compound command line.

When he says that it interprets the cmdlets and parameters, he does mean "Interpret" in the way a software

guy would use the word / term 'Interpret'.

A compiler compiles the whole program code into a runtime file, before running it.

An interpreter as opposed to a compiler, takes one line at a time (small bites) and then tries to run this,

effectively a step at a time.

That is why we often see as output in the results pane, some working result lines, then some red error messages,

and then once again some white working results.

Not all things need to be capable of being run when we try to interpret a script, or bunch of commands.

Summary (short) :

The PowerShell 'Engine' is an Interpreter.

PHH - 30th. November 2015.


Finding the Printers

=======================================================================================================================

=========================================================================================================

===================================================================================================================

==============================================================================

=========================================================================================

====================================================================================

PHH - 30th. October 2015.


Using 'Get-Member' to its full

PHH - 2nd. November 2015.


Examples with 'Files' & 'Folders'

For the old fashioned name of 'Directories' read the more modern one of 'Folders'.

=====================================================================

First thing to realise is that we have better ways and nicer syntax to work with Files and Folders

within 'PowerShell' than we had in DOS, years ago.

Lets try and explore, and then use the new object and command approach.

Remember that dealing with files and folders (and disks / devices) is never a 'smart' or 'cool'

thing to do - its even messy in .NET but has to be done to communicate with the O/S from

inside our code and solutions.

So we have to just "grasp the nettle" and learn how to interact with the filing system, from the

PowerShell environment, as best we can ;-)

*** NOTE *** finding files and folders, and sorting filtering and displaying these, is quite a different

exercise / process to the acts of reading and writing file content. For this reason we will make two

child section from here and will deal with these aspects separately.

Checking for existence of file and / or folder :

Luckily, we can do a test to see if a file or a folder exists in the same way.

Check out the following images and note the first test is for a folder, and then a file :-

We can do the same test for the folder and leave off the final back slash - see below :-

PHH - 30th. October & 18th. November 2015.


Reading and Writing file content

If we are to use PowerShell and read scripts and articles from other guys, then we will need

to be able to read and translate - or interpret - lots of different syntaxes for both reading from,

and writing to files on disk / device.

There are quite a few different formats, some old, some not Windows based, and some which

are more like modern Windows PS use.

We will try to cover the commonest to give us a suitable platform from which we can learn others.

Whether we like it of not, 'Redirection' has not disappeared, and will not go away.

*** NOTE *** there are two ways to use redirection to make files :-

' > ' means over-writing

' >> ' means appending

Let us Write some simple Files :

For our first few trials we will 'hard code' the file content.

Here is the simplest way to try these out - check below :-

======================================================================================================

===================================================================================================

And now for a 'cmdlet' :

We will explore using the command let named "Out-File" so we need some help from the PS help system :-

PHH - 19th. November 2015.


Finding and Listing - files and folders

PHH - 19th. November 2015.


Functions for Files / Folders

PHH - 19th. November 2015.


Chapter 1 - the 'Pipeline' - and Redirection

The "Pipeline" :

'Piping', using Pipes, and/or 'pipe-lining' are all common phrases /words to describe a data flow process.

'Connecting one command to another" is another way of thinking about pipelines and pipe-lining.

However, it is the data which is 'connecting' the commands.

The need for chaining commands is brought about by a need for 'data flow'. Data has to come from one

command and be presented to the next command for processing.

Alternative title - "using outputs as inputs" !

For any guy coming to PS5 having missed DOS and earlier command windows, then the 'Pipeline'

is similar to using STATIC methods in .NET, where we can use the output from one method as input

to a subsequent method, and so on.

When we talk of 'output' and 'input' we are talking of data items, and most often (always?) we will be dealing

with 'objects' as you will see quite soon in following chapters.

Obviously, in the modern world of IT, we are talking about collections of objects when we have more

than one. And even one would really be a collection of one item !

The ' | ' Pipeline symbol :

There is a special reserved symbol for the 'Pipeline' in command syntax, and this is ' | ' which is

usually to be found at bottom left of keyboard, just above the 'back slash' character - (Dec) 92, (Hex) 5C.

Yes, we do need to use the shift key to generate the correct character ;-0)

The codes are (Dec) 124, (Hex) 7C for the 'pipe'. Yes, sometimes folks refer to it as a 'pipe' and also they

talk about 'piping' too.

So we can say that the data from one command result is piped to another command. This is its simplest

form - two commands and data flowing from the first into the second.

However, quite quickly in our experience with PowerShell 5 can we arrive at input commands with many

(a handful) of Pipes, even when we are not doing anything too special - check below :-

See if you can 'read' the PS command line for yourself - the restricted set of results data items will help you

in this 'reading' task.

Lets now move on to the various sub-sections of this chapter . See you in the next ....................

PHH - 30th. October 2015.


as was - in DOS

Okay then guys, the 'Pipeline' has been around for many years. It was in DOS and is related to

on a Unix / Linux level, AND, apparently is VERY evident and effective in PS3 itself.

In this chapter we will attempt to unlock some of the power and flexibility that J&H refer to, for the

pipe-lining facilities within PowerShell.

For the old guys amongst us here is what we used to do in DOS, at the DOS prompt :-

=======================================================================

Yes, in the above image we see the DOS command of 'dir | more' being our way in the past

for controlling the output to the screen for long lists of output, so that we did not lose information

off the top of the screen before we had a chance to read it, and study it.

Enough said about DOS, I suggest we QUICKLY move on to another sub-section in which we

see the modern PS5 and 'cmdlet' way of doing piping and redirection.

Leave DOS for fond memories - Oh! and utter frustration at using stuff like EdLin and the rest.

Yuck !!!

PHH - 30th. October 2015.


Redirection

[ *** Does "Redirection" exist these days, or is it just 'cmdlets' under the hood !? - we shall see ..]

Redirection is the term used when we send output from some process, usually a command, to be the contents

of a file.

Here is an example from Ed Wilson's eBook :-

And if we now look at the File Explorer we see the following, and can open the new file in Notepad :-

=================================================================================================

And if we do not redirect the data from the console screen to a file, we see the following information on screen,

do you recognise it ? ;-)

Lets move on a set or two ................

===================================================================================

"Jones & Hicks" say :-

This (redirection) is a sort of alias for the Out-File cmdlet.

It’s not technically a true alias, but it does provide for Cmd.exe-style file redirection :-

  dir > files.txt.

===============================================================================================================

In the above image study lines 2 and 3 and then try a few trial examples of your own making.

Make sure you fully check to see that your commands have done exactly as you wished and/or required.

Here below we are using File Explorer to see the new file named 'files.txt' :-

============================================================================================

Lets move on a pace or two ..............

Symbols used in Command Line Syntax :

From doing tests in the PS5 command windows - console and ISE - it would appear that both a single

chevron ' > ' as well as a double chevron ' >> ' have the same effect.

Probably the double is a hangover from earlier days !?

AT the top of this section we used successfully the single form, now lets see a double form in action.

Check this out below - double chevrons :-

And the results seen in the next image :-

And the same works in the ISE tool as well - check below :-

Lets move on another few steps ..................

What about doing things the 'cmdlet' - command way ?

Taking *** CARE *** : use new style commanding in place of old 'stuff' :

I have to admit that doing and writing about the older style syntax shown above, did send shivers down

my spine just a little ;-0((

I think it is best to try and learn to do everything the modern and command ( 'cmdlet' ) way - then we

effectively have one way of doing everything - if you catch my drift !

Lets now look at such a command driven approach to the same problem - check below :-

==================================================================================================

We are piping the output data from the 'gcim' command, into the 'Out-File' command, with a supplied parameter.

Here is the 'part-script' being run in the ISE :-

Now then, I suppose we ought to do something in our command window to prove that 'gcim' and 'Out-File'

are indeed commands / 'cmdlet's.

Check the next two images shown below :-

Yes, above we see both an alis for the command as well as the full named entry for 'Get-CimInstance'.

And now the second cmdlet :-

So we have achieved the same result using commands and pipeline syntax, as we did when

we use redirection.

Lets give commanding and pipe-lining as much of a chance as we can - stick with one way of

doing stuff.

Lets move on, enough for one sub-section I feel - see you in the next one ...............

PHH - 30th. October & 18th. November 2015.


Different forms and syntax

PHH - 19th. November 2015.


Output to File

Which 'Out-' commands exist, and how many are there ? :

Before we study how to output to a file, and also the printer, using cmdlets, we need to know which ones

are available to us to use.

Lets use our growing 'PowerShell' knowledge to find out. Check the next image thoroughly :-

[ .. NOTE - the vertical line at the prompt is the cursor and not a pipe symbol .. ]

We will use and explore most or all of the above list, as they do look quite useful to standard guys

like you and me. I presume you are NOT a whiz Windows administrator.

In the next sub-section on "Output to printer" we will see an alternative way of finding the possible commands.

The 'Interesting' bit :

Okay then guys, this next information snippet is really interesting, almost funny.

Check out below what our gurus on PS have to say :-

============================================================================================================

This is even MORE reason to make sure we 'junk' the older syntax, forget DOS completely, and just

get on with using PowerShell in the modern way we can find in eBooks and web articles from recognised

experts and gurus.

So it NOT just about ".... it works, so what is wrong with doing it ? .... " lets get professional and do things

the right way. Yes, that means learning from those who know ;-0)

PHH - 1st. Nov. 2015.


Output to Printer

An alternative and GUI way to find and view the possible Commands / cmdlets is to use the

GUI icons in the menu area towards the RHS of the ISE window.

Check below to see where the two icons are that bring up a list box of commands :-

========================================================================

Of the two icons (the left one is in focus above) one adds a Commands pane to the ISE window,

and the other launches a floating window which can then obviously be repositioned minimised etc., etc..

The top otion (LHS icon) is for the floating window.

The RHS icon - shown below - is for the added and fixed pane.

============================================

So using the commands pane we can easily find the group of 'Out- ' cmdlets.

You need to launch this for yourself an experiment with its use - try your own printers.

=====================================================================================

Okay then folks, enough for now about the ISE environment, much more will be covered in

the relevant sub-section - Appendix ' I ' in the Appendices node / folder.

Lets move on ................

Using the 'Get-Printer' & 'Out-Printer' command lets :

Before we can use one or more of our own printers available to the Windows desktop, we need

to know just which are available via the O/S.

In the following image example we do both at the same time - however, you will just have to believe me when

I say that there is a piece of paper in my printer tray which looks exactly like the list shown in the following

image - except for the shortened lines with "..... " on the end.

Checkout these details thoroughly :-

Yes, it works and I can hear the printer springing into life at this very moment.

Issues to be resolved - the orientation needs to be landscape as columns are chopped off.

The above problem can be worked on however, as the basic approach works okay.

*** CARE / Warning ***

There are problems with the syntax shown below :-

With the above we get one piece of paper with "Get-Printer" typed at the top of it !?

There is a 'quick-fix' we can apply for this, as we can see below (and yes it does work okay) :-

Obviously the first approach sees Get-Printer as a literal String, and the (Get-Printer) as a collection of items

of type 'Printer'. The Printer class has properties of 'Name', 'Type' 'PortName', 'Shared', etc. ............

So the input object, here " (Get-Printer) ", is a collection of printer objects with properties including 'Name', 'Type' .....

The command Out-Printer get one object as input and that is the printer object which is built around "OKI C5600

linksys".

Okay folks, time to move on, see you in the next sub-section .................

PHH - 1st. Nov. 2015.


Multiple piping in one Command

In PowerShell work it is not a rarity to use multiple pipes in a single command.

In fact it is quite the reverse (opposite) we OFTEN see many piping symbols in PS command lines.

We need to get good at passing data along a command line 'chain' - from input to output and then this as input

again, and so on.

We just can't do PowerShell work without getting good and proficient with 'Piping'.

Its a bit like with SQL, where we MUST get good with creating SELECT statements.

===============================================================================

Okay then folks, lets use the 'Get-Printer' command-let ('cmdlet') to demonstrate how we can use multiple

piping within one command line in our scripts.

We will look at cases where we have two and three within a command line. Its quite common to use many more.

Let us start at the very beginning, where we simply get and display a list of our Printers.

Check out these details below :-

The desktop computer I am using is named 'BIG-T' (for big tower).

However, the command line can even be as simple as that shown below :-

Now let us try and find out all the members (Methods and Properties) relating to our Printer class of object.

Here we employ the 'Gm', or 'GM' or Get-Member cmdlet. [ ..the alias is defined / declared as 'gm'.. ]

The following image shows us some results from using this command :-

But in fact we can reduce this by adding a selection clause to our command - see how this is done below :-

And just to confirm in our minds what is happening, lets now get a list of Properties :-

[ .. notice that we have commented out the line to select the Methods .. ]

This list looks VERY suitable for some 'Sorting' - lets do a sort on the 'Name' column and by descending order.

Check out this command line syntax :- [ .. there is no meaningful character marks over the text - this is just part of the

previous line .. ]

=========================================================================================================

And here below is the full list Z to A :-

This all looks very nice, and just what we were after.

Lets now move on another step or two - lets also go back to the Get-Printer results set to do some filtering and sorting.

We are doing this so that we can get the command to work for filtering, them we can try the more complex 'Gm' command line.

On thing at a time ;-0)

If we wish to filter our results set in any way, we would be better to do it before the sorting process.

As with SQL work and querying, the idea is to Sort last in our results generating command line.

================================================================================================================================

Lets see what this looks like when run - check out below :-

Well, we have certainly excluded the OKI printers from our list. We now have 9 from the original 11.

Moving on ..............

Lets now once again include the 'Gm' piping which gives us a list of members.

The following command should now be a bit more familiar to us all - check this out :-

And here is the filtered results set to study :-

This all looks good to me, however, you know what programmers are like, they can't resist the chance to take things

just that little bit further ;-0)

Lets make our command line even longer and add a second exclusion condition in our filtering.

Oh! this line is getting very difficult to deal with when it is this long !?

And now lets run the command - check this out :-

Okay then, just as we may have expected.

Shall we now try to make our script look more like modern code rather than old fashioned console stuff in MS-DOS ?

Lets make a start and tidy things by introducing some of our own variables - checkout below :-

Well guys, it may have simplified things but there is still a long line to mess-up our print outs and screen displaying etc..

Lets see if this works correctly before we attempt to try and improve things still further - check below :-

This looks just fine, so what can we do to further improve our script content and line length ?

Well, in a web search I found that we can break a command line at a piping character, the ' | ' symbol.

So now we have the following :-

And just in case you don't want it in descending order here is the alternative, shown below :-

Notice above I have commented out the last part of script line 7 and so our results lines start with

'B' and not 'U'.

Before we close this sub-section, have you noticed in all these results set displays (and those in other sub-sections) we are provided

with the name of the Type of items being listed - YES, I know they seem long and complex but at least

they are clearly stated ;-0)

** Note *** to shorten lines further I tried the use of the character ' ` ' at the top left of most/many keyboards.

However, I could not seem to get it to work for me on my current platform. I will continue to search for a solution

to splitting long lines.

Enough for now, lets move on to the next sub-section - see you there ...................

PHH - 1st. Nov. 2015.


Where to put the Pipe symbol ' | '

Luckily the placement of the pipe symbol ' | ' allows us to be flexible in our command line work and also

our scripting.

The following example of a command line in the console pane shows how it is probably easier to input it

in a long continuous format - check below :-

However, it is harder to read and mentally 'parse' than the alternative way we can probably more easily use with

scripts and scripting.

Study the same command shown below when it is split up into its constituent parts :-

==================================================================================================

It would appear that the console pane requires the ' | ' to be placed last on one line rather

than first on the next line.

I would think that .NET guys will prefer this split line formatting - I like it ;-0)

Now then, we can of course type a command line in a similar way but it feels a bit messy while doing

it this way - see below :-

I suppose you could get used to typing this, but since I always intend to use ISE and GUI panes

etc., I am not going to try very often !

Enough for now - lets move from this sub-section to learn some more interesting PowerShell stuff.

PHH - 18th. November 2015.

Addendum :

Don't miss out the space before the pipe symbol - no (sorry) its more complex than that - may be a difference in

ISE and the command console pane.

Here is the console input and the spaces are missing in this example :-


The 'Select' command

Well guys, the 'Select' command is as important, and as frequently used as the 'Sort' command.

Both are 'aliases' for 'Select-Object' and 'Sort-Object'

Try this command line to help explain things :-

And in fact we can also add the other two search text strings of 'Where* ' and 'Group* ' to the list of

inputs in the above command line.

If we do this then we get all the clauses for SQL select statement comparability.

Check the following details carefully :-

'Select' allows us to choose only some columns (properties) from those available, as well as choosing

only some rows of object item data, under certain circumstances, or in a limited way.

Filtering allows rows to be discarded in many ways, using complex conditions - BUT - when it comes

to getting the fist 5 lines or only the last 13 lines, then 'Select' is our friend ;-0)

Lets look at some simple and straightforward examples of how to use 'Select'.

Study the following command line :-

From the full possible results set we see lines 2 and 3 reducing the rows returned, and

line 4 only returns the three columns / fields / properties that are specified.

So it reduces results output in both the vertical and horizontal direction.

Lets do the same thing at the command prompt, typing the harder way (more difficult to deal

with typing errors prior to where the cursor happens to be.

Obviously the results vary as to when they were acquired.

PHH - 8th. November 2015.


Other 'Out-***' commands

PHH - 18th. November 2015.


Out-Default

Okay, this below makes good sense but also suggests that we may not use it for a while - till we get

more experience under our belts ;-0)

PHH - 18th. November 2015.


Out-Host

We can use this easily if we so wish, but it would also appear that this is what we get when we ask for nothing special.

Checkout the details below :-

PHH - 18th. November 2015.


Out-Null

PHH - 18th. November 2015.


Out-String

PHH - 18th. November 2015.


Out-GridView

Be prepared for 'Fun' - this looks to be a VERY useful command let indeed ;-0)

Any of our collections (even of unitary length) can be displayed easily in a nice data grid view window.

System data and our own class collection data (list and arrays) can be displayed in a neat fashion.

PHH - 18th. November 2015.


The 'Pipeline' - going further / more advanced

Jones & Hicks say the following :-

"Although PowerShell’s pipeline capabilities can be complicated, they’re probably easier to learn than

more-complicated programming skills.

By learning to manipulate the pipeline, you can be much more effective without needing to write scripts."

*** Note ***

Generally speaking, commands sharing the same 'noun' can usually pipe to each other by value - (ByValue).

Being a .NET developer I see it simply in terms of object and property.

The item objects output by the first command must match the type of a property on the object associated

with the second command. More of this later in this sub-section.

First a simple and straightforward example to start us off. Lets look at noun 'Process' - and 'verbs' Get and Stop.

Check this out below :-

Notice in the following image we have running an instance of both Notepad and Wordpad :-

If we now pipe commands 'Get-Process' and 'Stop-Process' (restricting the finds for safety!) we

can see that below we are likely to do something noticeable :-

Yes, the monitor on my right has the screen cleared as the two windows associated with Notepad

and Wordpad are closed down - not a lot to look at below :-

PHH - 26th. November 2015.


Chapter 2 - 'Filtering' & 'Sorting' & 'Selecting' & 'Grouping' results

'FGSS' - 'Filtering, Grouping, Sorting and Selecting'.

This is a VERY important part of PowerShell 'commanding' and general use.

I say this because commands and 'cmdlet's related to FGSS are used within the scripts we create

as much as just typed at the console pane prompt.

They are also used a lot by others, and Windows O/S managers in particular.

If we get a working 'feel for', and 'grip of ' command ways to FGSS, then we will need to write far less

script text/lines to do the same thing.

Here is a very good example - check this out below :-

Previous, in days gone by (a couple weeks) I was doing such tasks as that above by writing script

in a similar way to using C# / VN to code up an app. Remember in .NET we do not have the benefit

of commands and 'cmdlet' use.

So what would the script be like for us to do it the hard way ? - or should I say the 'Not PowerShell' way.

In the following image I have commented a couple of lines used for development and testing (3 & 8).

Study the script lines and syntax, carefully :-

And now remind ourselves of what we can do in a single command line - see below :-

So with this knowledge of PS5 we can change our script test to a much simple form as shown below :-

The summary of this is that it is important to know how to script and use the syntax to do what

.NET guys do best 'code' - BUT - we must also know all of the command ways of using PowerShell

so that we can do things the smart way, and also understand what other guys do in their

published work - scripts and articles.

See you in the sub-sections for FGSS .......................

PHH - 30th. October 2015. & 6th. November 2015.


which 'cmdlet's are available

If we refer back to SQL 'select' statements we get an idea of what can be done when it comes

to requesting and processing results for return and possible display.

Here is a simplistic outline of such general SQL query statements :-

SELECT ........................

FROM .....................

WHERE .....................

GROUP by ...................

HAVING .........

ORDER by .......................

If we now look at the existing 'cmdlet's defined for us in PowerShell, we see the following :-

[ Yes, we can do a lot with a short command line ;-0) ]

Okay then folks, we do not see any command let with a name suggesting anything like 'FROM'.

This is because the piping syntax provides the input data to each of the above 'cmdlet's which is

related to filtering, sorting, selecting and grouping. Not all the above are used for this purpose.

The 'non-red' entries in the above list can all be found in the short list of command lets, except for

'HAVING'.

So we are particularly interested in these four :-

Select-Object

Where-Object

Group-Object

Sort-Object

With these cmdlets working together, as well as an initial 'pipe' to provide the data to be processed, we

can do just about everything we could do in T-SQL script outside of the 'FROM' clause.

In the next few sub-sections we will see how to get the most out of these most useful commands.

*** hope !? *** we may even be able to do the equivalent of a HAVING clause if we apply the Where-Object

again, after the 'Group-Object is called.

Sorting is slightly different in that it may be used / applied more than once in a piping series.

See you in the next sub-section, where we will start to get some interesting results.

PHH - 9th. November 2015.


Selecting

'Selecting' - which Fields / Columns / Properties :

If we get into our heads the idea of a table of results, or data records, and that the 'select' cmdlet allows

us to choose which columns we require, as well as which rows of data.

This is much like the SELECT statement in SQL Server usage.

As well as selecting required data columns for output in the results 'set', there are ways to select the

rows of data.

Later we see a special 'extra' bonus which is of the "set algebra" type of command.

By Columns :

To select by column we are simply telling the PS5 system which columns (or fields) we require and

any others are ignored.

When we property / column select then the number of rows in the results set is unchanged,

unless we use a second or subsequent 'select' command as seen below.

Here is a simple example using the active Processes on the system :-

Now then, we appear to have another (and slightly more complex) way to do the same thing

as far as column selection is concerned.

In the image seen below we are using a 'select-object' command let, which is probably a way of

us being able to do more than in the previous simple syntax of "select WS, ProcessName, Id".

Check out these details, we will see how to use the 'Select-Object' in other ways later on in the text :-

*** Note *** that the order we specify our columns is the order they are shown on the screen.

And of course we can do silly things too ;-0) - see the next image :-

[ .. in SQL the Select statement can have multiple column entries - why not here !? .. ]

Here is my first try :-

Oh! - the PS5 system does not like that.

So lets try another way - with the more complex syntax using 'Select-Object' :-

So this is one reason to use the more complex syntax - we can push it further, and get more out of it if

we know how to use the command let in the first place.

Now then lets make a tidier and more meaningful test of multiple column display - check this out :-

By careful not to miss the 'backtick' character on lines 2, 3 and 4 (RHS) and no following spaces.

By Rows :

By Frequency / Count :

An 'extra' bonus - finding just the unique items in a collection :

This is a brilliant 'find' ;-0)

When and why to NOT place 'Sort' last in the command 'chain' :

Get-ChildItem c:\windows\*.* | Sort-Object length -descending | Select-Object -first 3

PHH - 9th. November 2015.


Sorting

Sorting :

By 'Sorting' in PowerShell we are meaning the action of taking some results set and applying a 'sort'

condition to make the results set come out the way we wish in the order we require for the individual items.

Also be aware that we usually sort as the last activity of the sequence we are applying.

On rarer occasions we may sort part way through a more complex sequence of actions - BUT - rule one

of PS5 scripting at least, is to keep things as simple as possible.

Scripting allows us to simplify commands which more experienced (older guys) may like to do in one

long command at the console prompt ;-0((

We will keep things simple - as far a complex single commands are concerned.

Lets start with a very simple example - check below for details :-

Yes, our full set of printer items is listed in the console results pane in alphabetical order A-Z of the Name property.

In the above example we have all properties displayed by default.

Lets now only display the first two columns / properties - check below :-

In the above example we have done our sort action last of all of the piped commands.

However, we can change this and try something else as seen below :-

Notice that we have sorted before or selection and get the same results.

Do be aware that it is not the same when it comes to Sorting before Filtering, as this at

least can drastically affect the performance. I am not sure about the order of the results.

Stick with what we use as an 'adage' in SQL - sort last if there is not a reason not to do so!

"Multi-Field" sorts - was 'Multi-Key' sorts in days gone by ;-0) :

Okay then guys, what if we wish to take a bunch of result items and sort then first by one

property and then secondly by another.

Here is a simple example - check it out :-

And now lets look at the relevant section of the output display :-

We could do with tidying this up, and making it more clear and readable.

Here is another attempt :-

And the results of this :-

So lets move on, and instead of displaying all, and then capturing only part of the screen results, we

only display what we want to see - more like reality and 'real life'.

Whoa !! - lets shorten our command line, I will use the script editor in ISE - you can try the command console if you prefer.

And of course we can sort into Z-A or descending order - check this :-

Enough for now, its up to you to go and do some trials and practising ;-0)

You will see more of this type of commanding in later sections and chapters of these eNotes.

See you in the next section .................

PHH - 9th. November 2015.


Filtering

Filtering :

The general term 'filtering' can be brought about in different ways in 'PowerShell' commands.

By 'filtering' we mean taking a bunch, or group, of objects/items and reducing the set to a smaller

one depending on some condition specified.

Look at this very simple way of doing this in a short command line - check the details :-

This gives us all items with a 'w' somewhere within the Name - above entitled 'ProcessName'.

The following also works :-

However we are not stating which column or field to search !?

Lets first see the results - or part of them - then we can discuss how to filter on other fields / property values.

Before we get more complex in our filtering commands, lets see another and different selection and sort command in action.

Study this in detail :-

The problem is that not all property columns can be as easily accessed, or addressed.

See what happens when we try the 'Type' column / property - check below :-

So we obviously need a more complex way to be able to get at all property values.

Lets now look at this further method of approach :-

We still have one command line but the extra complexity is required so we can access all existing fields/properties.

Above we are accessing the 'Type' property, even though they are all 'Local' anyhow ;-0)

PHH - 9th. November 2015.


where / Where-Object

The 'cmdlet' "Where-Object" has an alias of "where", and so they both can be used interchangeably.

Using 'where' makes our command line read more like SQL select statements, especially when we

also use the aliases of 'select', 'group' and 'sort'.

Before we get to SQL select 'look-a-likes', lets start simply and do some selection work.

Here we see how dirctly fron the 'Get-Command' cmdlet, we can filter on some specific text strings :-

If we now build on the command we have used above, and add some other constraints, then

we can reduce our results set accordingly.

Check out the following details :-

Notice in the above image detail we are using the alias form of the cmdlets - 'where' and 'sort'.

Now then guys, let us take this opportunity to try and apply a quite complex 'where clause', or filtering condition.

By splitting up our condition into two 'where' clauses we can reduce the risk of coding confusing logic.

Out of interest, we can do this sort of thing with LINQ syntax as well. Checkout below :-

Well folks, its certainly looking good.

Let us now try and make the full command line look even more like an SQL statement - lets introduce the

'select' alias cmdlet see below for details :-

If you try and combine the where clauses you are at risk of getting the logic wrong, so why not do

our data filtering in more than one stage ?!

Lets complete this part by improving or ordering, and sort on two keys, or column / fields :-

Yes, the above looks good, and gives us something like we are after.

Also notice that the results are really to do with the stuff from which we are composing our command line.

I think it is time for you guys to have a try at some of this fun stuff ;-0)

Before you do, have a look at the next image for an alternative command line relating to the above :-

And particularly this next one :-

*** CARE *** with Aliases !!!

I have just had some infuriating lost minutes (many) trying to work with Aliases and Cmdlets as they are sent as a results

set from the 'Get-Command' cmdlet.

By all means have a play around but be aware that it may be that there is something clever (odd ?) going on under the hood.

I will leave you with two images I made during my tests :-

And now this :-

Enough for now, lets move on to the next sub-section and learn something new ;-0)

PHH - 25th. November 2015.

Addendum :

Exploring the missing Aliases for sort, select, group and where in some commands.

Here is a script which attempts such a results output :-

And the 'GridView' object when instantiated and shown on screen :-

Well the above looks good in one way and bad from the absence of 'alias' entries !?

Checkout the following command line, and try it for yourself :-

From the long A-Z sorted list lets search visually for our entries.

No 'sort' alias - see below :-

No 'select' alias - see below :-

As I said previously I think at times the Get-Command cmdlet does something odd under the hood ;-0((

PHH - 25th. November 2015.


Doing all three at once - 'reality'

When it comes to doing real work with PowerShell then we probably most often do all three of

the 'FSS' actions (activities) at the same time. Think of filtering, sorting, and selecting as a set of common

procedures to provide us with suitable data results - usually collections.

For any of you guys who are SQL Server users and coders (includes LINQ coding) then you will

also do this most of the time.

We rarely just filter, or just sort, or just select ! So we need to get good at combining these activities.

Filtering, Sorting and Selecting :

PHH - 9th. November 2015.


Grouping

Let us try to help ourselves - and use the HELP from within PowerShell - check this out :-

Okay then, like a lot of help pages we need to NOT be put-off by the details, and start to

pick out bits that look useful, and just try them - experiment and explore !

Lets try and get a few examples :-

Oh dear! - this first example is not a good one on the fun and exciting 'scale' of things.

Here it is more clearly :-

But for me to run it I need to move to a better folder - as far as the likely results are concerned.

Here is what I managed to do :-

Yes, we were never really going to get much of an output trying to group length values, in my opinion.

Lets try another group command based on extension type - study this carefully :-

*** Remember that the cursor at the prompt looks like a piping symbol - see above. ***

According to these results we should see that in the chosen folder we have seven sub-folders and 49 PDF files - here is

a snap-shot of that folder.

===================================================================================================================================

Well, although that was a better example, we can still do much better I feel ;-0)

Yes, it would look as if I have a much better results sample, simply by changing the folder.

How about this then ? :-

Well at least we have some slightly more meaningful groups.

And with a bit of thought and tidying up we can do this and see some sorted results :-

Now that we have a bit of a feel for things we can try out a new example / trial of our own.

Here is something I have tried to do in a more long-winded way with scripting :-

And once again we can sort as well - try this as an improvement :-

After playing around with the grouping options I managed to find in the HELP text some pointers as to

how to remove the group listings on each of the results lines - could be helpful under certain circumstances.

Here is the extra parameter in use - check thoroughly :-

This second command is identical to the first, except that it uses the 'NoElement' parameter to eliminate

the members of the group from the output. The result is a table with only the count and property value name.

And now, since we are .NET guys we can get a feel for these objects and their properties and come up

with the following script based on commands more than coding stuff :-

[ .. remember the index is zero based ! - cheers Don .. ]

I must admit it is starting to feel as if we are getting somewhere with this PowerShell malarkey (stuff / thing).

Time to move on, see you in the next sub-section.

PHH - 9th. November 2015.


Displaying results

Results are data - almost the same thing. When we get back results from querying the

operating system with our power shell command-lets, we need to show it on screen in

a suitable manner.

Usually data to be displayed is a 'results set' acquired by using one or more cmdlets and

then some filtering, selecting, grouping and/or sorting.

Depending on the amount and type of the data, we need to list or tabulate it.

Here is a simple example of a Table output :-

Yes, tables in this format shown above look most useful indeed.

How about a list ?

Lets study the next image to see what is different to above - checkout this simple list :-

We can now go and explore more about Lists and Tables in the relevant child sections

from here.

See you then ............

PHH - 26th. December 2015.


Lists

PHH - 26th. December 2015.


Tables

PHH - 26th. December 2015.


Chapter 3 - using 'Variables'

If you don't know what a variable is, and what it is used for, then you should really be learning

something other than PowerShell 5.0 at this moment in time ;-0)

We will assume that all we need to do is make clear what data types can be used, and what are

the problems and issues with using variables in PS - of these types.

We need to explore fully just how variables are used by experts of PS5, rather than just doing things

our own way.

A good comparison with the world of .NET as well as .NET coding is more than worth it !

There are 'Gotchas' to be aware of, so take care. Us .NET C# / Vulcan guys are at risk.

Finally, when we get into wishing to use more complex types like 'ArrayList', and 'List<T>', we do then

hit the age old problem of 'Namespaces' and pointing our script to the right place in the framework.

Lets do some learning ...........

What do Variables look like ? :

In PS all variables start with the ' $ ' symbol, or dollar sign.

Here below are some that I have added within ISE, and they work okay :-

The five different variables are comprised of four separate data Types.

We can find the variables in memory for the PS session in hand, by using a

provided 'cmdlet' - checkout below :-

You will see there are more than we have used so far, and that is because I wrote and

ran the extra script lines shown below - I have improved the variable naming so that it

is more useful, and more indicative of what the variable is, or stands for.

Checkout the following image of these extra lines :-

This above, all seems simple enough, but what of other variables - we filtered out my personal

ones using ' *my_* '

Before we move on, it will be useful to see the other variables in existence - checkout below :-

[ .. notice the PowerShell way to filter out those we have named ourselves .. ]

Because I prefix all my variables in my commands and script with 'my_' I can easily filter these out, or not. As

the case / situation requires me to.

The list would therefore suggest to me that the following should work - lets try it :-

And here is another filter where we find all the variables beginning with 'm' or 'M' :-

Yes, above seems all okay and quite understandable.

If we don't have a fixed prefix then we will get all our variables mixed up in a list with those made

by, and required for, the system.

I like this simple way ..................

Time to move on, into the first child sub-section of this chapter.

Lets go and examine in detail the data Types which can be stored by variables, and

then effectively used in our commands and scripting.

See you there ...............

PHH - 8th. November & December 1st. 2015. (after Oct 30th.)

Addendum :

There are other ways to list out variables.

One GOOD way is to use the PowerShell 'Provider' system.

Below is a reminder of how to find the usable drives :-

Notice the one we require - it is 'variable'.

lets now swap to the data Provider for 'variable's :-

And so we can now use Dir or Get_ChildItem, or gci - as seen below :-

Each of the above three syntaxes provided listed results and in a format of A-ZA-ZA-Z.

So in the above image look for what..., then $, ?, and so forth.


Types of data stored, and 'Casting'

*** NOTE *** The term 'Casting' is given to the situation in which we force a generalised data value to

be a specific type and make the assigned variable this 'forced' type.

By 'Casting' we can be sure that the variable is of the type we require - at the time and then afterwards,

for as long as the variable exists.

==========================================================================

As with all scripting and coding languages, we need a range of data types to support our functions and / or

programs written / scripted.

Luckily for us in PowerShell we tend to use as the core data, those data types which are the standard

ones in the .NET framework. That is a relief for us coder guys using Vulcan and C# - nothing changes.

However, when we move over into the world of SQL servers (various flavours) then we have to consider the data

types belonging to T-SQL. Lets leave that problem till MUCH later ;-0((

Here below, is an image I found while researching PowerShell 5.0 - it will prove useful for our data explorations.

Note that this is a summary of the commonest types we see when using PowerShell, and these are also

the very same types we see in .NET - as far as I am aware.

===================================================================================

[ .. there are others as we shall see when we do our experiments .. ]

The data type names are in square braces or brackets, and it is these ' [ ] ' which are also used

when we 'Cast'.

So what we need to do now is try out some learning examples, and do some personal explanatory

work with commands and 'cmdlet's.

Here is a start with large integers :-

Line one shows some working script - BUT - it is a little "over the top" in that we are 'casting'

on both sides of the declaration of the variable.

If we leave the cast on the RHS then the script / code works just as well.

Here is how it looks :-

Notice that it is helpful to use the 'gm' or Get-Member 'cmdlet' to help identify what type of data

we likely to have stored in our variable.

Check you can see 'System.Int64' in the above image.

Please note that you need to look in other sub-sections of this chapter where we consider variables

being automatically cast to be other types than what we imagine will be the result.

Auto-casting is done by the interpreter engine when it tries to do possibly too much for us, the developer.

Before we move on, lets see another syntax style for casting numbers - once again the large integer :-

Notice the trailing 'L' after the line of digits - this postfix style is quite useful !

Lets move on ................

The 'Decimal' data Type :

In the following image note the 'D' at the RHS of line 10 - this forces a cast to 'Decimal' :-

So in the above image, even though we have the same value as was 'auto-cast' to Int32, we can force the

data type by casting in this special way - using 'D' as a 'postfix'.

Lets move on a step or two ...........

DateTime and TimeSpan :

Every programming guy worth his/her 'salt' will have to deal a lot in Dates, Times and time spans, or

time differences.

In .NET this is a doddle - much easier than in many other languages. We have a specific section on

these but we we quickly mention them here.

Okay then, that looks right - as seen above.

And the Get-Member details !? - check these out :-

PHH - 8th. November & 1st. December 2015.


Declaring our variables, or not !?

Guys who are .NET coders and developers will be used to declaring their variables in

a tidy and organised way.

We also are used to STRONG typing, such that a named variable is given a 'Type' as soon

as it is declared, and before it is used in code.

Also mistyping variable names is a bit of a thing from the past - ancient history ?

I suggest we explore tying to always declare our variables with the 'cast' that gives them the

Type that we require, as well as possibly providing them with an initial value of the chosen

Type we have selected.

We can get some strange things happening, and errors hard to trace, if we are at all sloppy

with our variable declaration and general use in script.

Moving on .......................

How to Declare and Type a new Variable :

Lets look at the various ways in which we can declare a new variable.

In the following image we see some variations in the way declaration can be done.

Check out carefully the script line details :-

In the above image we see that all four variables must be 64 bit ones as they have all taken

the value of the same LARGE number.

However, with a small change in our script we get an interesting difference at run time.

Checkout these details to work out for yourself the change :-

Yes, because we have not cast our variable named "$myLargeInt64" with the correct 'Type',

when we run the code the value assigned to the variable seems to dictate the type, and

simply because it (the value) is small enough, it becomes an 'Int32' type.

*** Try to force / cast the required Type - don't leave anything to chance! ***

Here is another way - its called a short-cut and is VERY handy and useful :-

Notice the upper case (capital) 'L' at the left hand side of line 10. This mean 'Long' integer.

If we happen to leave a space between the numeric text and the 'L' we get an error :-

There are other short-hand 'casting' letters, or characters, and these can be found in the

sub-section on data Types. Chapter 4, the numerical sub-sections.

Here is a screen clip to demonstrate a different cast :-

Time to move on ...................

See you in the next section.

PHH - 8th. November 2015.


Sessions in PS and Variables

When we first open Windows PowerShell ISE or the simpler 'Console' pane we also start a 'Session'

at the same time.

A session seems (normally) to last as long as the shell and / or pane is open.

As we add and run more commands to our session, the 'History' grows for that session, and any variables

used are kept 'persistent' - they and their values remain in 'session' memory.

This simply means that at the prompt we can use variables (and their values) from previously run commands.

At any time we can get a list of session variables using the cmdlet 'Get-Variable'.

Unfortunately, we get system (or PS engine) variables mixed up with our own, the we create in out scripts

and commands that we run.

If we always name our variables in a certain way, we can at least then filter out just ours for viewing.

Take a look at the following image and try to figure out what my naming pattern is for my variables :-

Yes, my variable name convention is to prefix all names with " my_ " so this next image fits this :-

Notice that line 27 works - BUT - this is not normally my style of scripting / coding. I did it so we could

have a bunch of variables placed in session memory as quickly as possible.

The data types of the variables ought to be the same for each - and they also will be that of the first one

named " $my_IntTest ".

Moving on ....................

Let us see the script code which generated the variable in the first place - check out below as we

cast and re-cast the variable named ' $my_IntTest ' :-

The above is the first 'gm' (Get-Member) output from line 19, and the next image is the second

one from line 23 - check this out :-

So in the above image line 21 is the last place a type is cast for our variable, and it is as seen,

of type 'Decimal'.

So in this case all the other assigned variables in the line on position 27 below, are also of Type 'Decimal'.

==============================================================================================

Let us now start an interesting exploration to see if we can use the PS cmdlets to find out the

Type and Value of variables which are stored in the session data store.

Lets first see the full list of 'my' variables - check below :-

And from the above list we will explore only ' my_IntTest11 ' .........................

From previous experience it does not seem unreasonable to try the following, even though it will turn out

to be NOT what we want. Check this for detail :-

Yes, it looks as though the cmdlet 'Get-Variable' returns an object of type "System.Management.Automation.PSVariable".

Lets do an experiment ...........

==============================================================================================

In the above experiment we can see that the object returned by the code in braces, has members as listed

in the drop-down.

If we now use the 'GetType' member we see this shown below :-

Yes, it is certainly NOT the type of the actual variable itself - we need another way to go about finding that.

Lets go back and study the full members list for the 'PSVariable' - see details below :-

From the above details it looks as though we should explore 'Value' , the property.

Let run with that for a moment :-

Now then, this looks quite hopeful at least we have the value in our grasp / hands.

So if all things PS are objects, then what Type is this value ? lets try this :-

Yes, we can see that our ValueType has a name 'Decimal' which is what we should expect

from our executed script farther above.

This is all looking very promising, lets put it to the test with something far more complex.

How about an array of large integers ? Check this for details :-

Remember the @() means assign an empty array where the element Type is that of the 'Cast'.

So we have an array of Int64 elements.

Now check this out :-

And while we are at it, we may as well refresh our minds on how to access the array elements and get

their value for use elsewhere and display etc..

And in fact line 59 has an non-required set of braces, so we can simplify things to this :-

Okay then folks, obviously we need a lot more experience with variables of all types and used

in all sorts of ways, but I feel we have the basics to get us going. It has been quite interesting

I feel.

See you in the next sub-section ..................

PHH - 4th. December 2015.


Possible problems / issues / 'gotchas'

Misspelling the originally typed in variable name.

Combining variables of different type, inadvertently.

PHH - 8th. November 2015.


Namespaces - finding and using them

*** NOTE *** It is helpful to remember that Generic Classes do not contain any STATIC members.

===============================================================================

For us to use .NET classes for our data types we need to know, or find out, in which

namespace they reside.

I regularly use the search tab facility in the Help Viewer. Below is an example of what was found when

I searched on the Generic namespace - check the image details :-

=============================================================================================================================

Sometimes we can search on the data type class itself, but here it was handy to find a bunch of classes all within the Generic

namespace itself.

=====================================================================================================================================================

===============================================================================================================================================

=========================================================================================================================

PHH - 8th. November 2015.


Lists and collections - Array, ArrayList, ....

General discussion of collections and lists :

Very often in the body of text and in general discussion of 'stuff', the words list and collection are

used in a 'general' sense, and are NOT referring to a class in a framework - like .NET.

However, in .NET coding experienced users do use both the 'List' class and the 'ObservableCollection' (OC)

class to great effect. Usually in the generic form of List<T> and ObservableCollection<T> where 'T' is

the supplied 'Type' - so all items are strongly typed.

When I came to these initially, I did not know how to instantiate them, but now I have gotten into using

both ArrayLists, as well as Lists and OCs. I had to experiment a little with syntax.

General issues :

The possible problem with list and collections is that we most usually don't know how long these will

be as objects, when we create and even use them - how long is a piece of string ?

The bad thing for us with Arrays is that these are fixed in length, and in .NET were more difficult to use,

the good thing about ArrayLists is that these are adjustable, 'on the fly'.

In PowerShell the 'engine' seems to provide a handy way around this fixed length limit - BUT - I don't

know how this affects the performance when we get to very long arrays.

We can have Arrays and ArrayLists of any class of object. As too Lists and OCs.

There is further information on Arrays, List and Collections at the end of chapter 4, the

very next chapter. Go and study what is there after reading this sub-section.

Arrays :

The System.Array class is one of the first in the .NET framework - yes, its old, historic even ;-0)

Here are a couple of ways to declare an Array variable :-

Note that we can't use 'New()' as for ArrayLists, Lists and OCs - these are shown below.

Obviously, a similar syntax is used for Arrays of other Types, like 'Int32' and 'Double' and 'DateTime' etc..

ArrayLists :

Before we can declare an 'ArrayList' type variable, we first need to know which Namespace it is in.

We can find that out by using the search facility in Help Viewer 2.2 from Microsoft - line 2 below

shows what this namespace is :-

[ .. yes, we can instantiate with the 'New' method .. ]

As seen above, to add elements to an ArrayList we use the 'Add()' method - which was

unavailable to us when using Arrays.

Here is another example :-

Lines 13, 15 and 16 show how to access the items in the collection as well as find the

number of elements in the list object - list being a general term for an ArrayList object.

List<T> :

The following image details will not require any discussion, they are like above with just another

and separate namespace being used - check this out below :-

Note the syntax change from .NET and ' < T > ' to ' [ T ] ' on line 1 above.

Lets move on ..............

ObservableCollection<T> :

Once again, with the correct namespace and correct syntax we can understand the rest quite easily.

Study these details :-

I will leave you to try the Read Only version of 'OC'.

To see more and also the extra classes of Stack<T> and Queue<T> ... and more, then go to chapter 4

and the last main section there.

Lets move on to discuss Sorting from within the class, as opposed to using a cmdlet.

Sorting - via the Class 'Sort' method :

Although PowerShell itself provides some very useful command-lets for sorting and filtering and the likes,

we must not forget we still have the full .NET facilities as well.

Below is an 'ArrayList' being sorted in order A-Z - this is a sample from the 'Help Viewer' knowledge bank :-

=======================================================================================================

And now here is my simple testing :-

And as well do the test, note how we need the double quote to allow us to use the escape

sequence work with the 'n' newline character - a back-tick and then and 'n' - check below :-

Time to move on, we have learned a lot, and probably enough for the moment.

See you in the next sub-section .....................

PHH - 8th. November 2015.


Chapter 4 - 'Strings', 'Numbers' and 'Collections'

By the very nature of this topic, it is bitty, and a bit mixed up - in that there are so many ways to tackle

the topic, and so many little - but important - fiddly things to cover.

So just bare with me and we can have a bit of fun while learning quite a few useful PS techniques and

tricks on the way to 'personal enlightenment' ;-)

=========================================================================

A bit on Strings :

Remember, a 'String' is a data type, and as such we can have variables which are String types,

as well as properties of objects which are String types.

And of course we can have literals which are Strings.

*** Be Aware *** that we have a certain amount of String behaviour built into the PS engine,

but on top of that we have all of the String related .NET stuff as well - this is particularly for our

scripting use.

Let us have a quick look at some parts of a simple script section to get a feel for all

things 'String' ! - as part of the PS engine.

Let us first of all declare our own variable and assign it with a literal - then print the newly

made variable - check this :-

And since a String is an object we can access and use properties and methods.

So just like in C# and Vulcan.NET we can do the following :-

Okay, I know, we don't really need to use the 'ToString' method on a String type object,

but it does illustrate a point - a Method member exists.

And while we are at it, lets see one way to add a couple of comments - check below :-

[ .. get used to commenting your script with # and <# #> where necessary .. ]

Notice that the string / text comments do not appear in the console at run time - well in the results section of the

console that is.

In the above image they appear at the top of the console screen because we are running a bunch of script code

which has not as yet been saved into a script file.

Moving on .............

So what happened to the good old MS-DOS 'rem' we used to love and use a lot ?

Here is a trial :-

Yes guys, I feel we should really put DOS to one side.

Lets just learn how to do things the PowerShell way ;-0)

As well as using the best way, and most modern way, we do need to be flexible enough in mind

and knowledge to understand script and commands from other articles and web sites ;-0((

That is just a necessary reality.

This also means that even though we have intellisense in ISE we need to be able to read and use

the various aliases in the cmdlets. Personally, I keep away from alias use, maybe its my .NET training !?

A bit on Numbers :

A bit on 'Collections' :

PHH - 30th. October 2015.


Properties of Objects

Complex data objects are made up of defined properties which in themselves are of standard data Types.

Let us see a simple user defined class of object.

Here below is my Car class (developed from a much simpler class of Ed Wilson in a web cast) :-

========================================================================================

Lines 3 and 4 above show 5 Property definitions. Two String, two Integer and a 'DateTime'.

As well as the Properties we have two Constructors but no basic Methods as yet.

To the above we could add a Method called 'Description' which returns a string made up from

more than one of the Property values, and some general text.

When we wish to use complex objects we can assign their properties just as we assign variables.

Here are some examples of assignment :-

=========================================================================================

Obviously, in the above image code we could assign existing variables to the object properties.

Lets see how this will look when we make the required changes :-

Final Remark :

Of course an Object can have a Property which is a collection, but then that's probably going too far

at the moment ;-0)

Lets move on ......................

See you in the next sub-section.

PHH - 1st. Nov. 2015.


Variables - as used in Scripts

Here is an interesting thing to take into account when working with scripts in ISE and the

console / results pane at the same time.

The variables will often be left in memory - LIVE as it were.

Check out these next two images to see what I mean :-

After the script was run, and completed, I have simply type in at the screen prompt,

the variable name and pressed enter.

The value of this variable is still available - here is another trial :-

Yes, we can even do some simple maths with it.

So do be aware, the variables are in the system - I am not sure what cleans them up,

or removes them. We need to find out I feel.

Maybe one way round this is to declare them in script to only be in scope while the script runs !?

PHH - 1st. Nov. 2015.


'String' manipulation

Okay guys, this is a VERY necessary section, even if it feels like we have been here many times

before in our programming and coding careers.

However, because we have had previous experience we are likely to find it a bit easier, and quicker,

this time around ;-0)

There is manipulation and there is also conversion - each has its place and each can be detailed as

well as being a bit tricky.

Lets get going ...........

Declaring a String variable :

There are a few ways to do this, lets start out as simply as possible - check this out :-

==============================================================

Once we have the newly declared variable we then have intellisense on it as shown below :-

========================================================

We really need to see all of the available public members of the System.String class.

However, rather than using the intellisense screen display, lets use PowerShell itself.

Look at the next two images to see first of all how it is done (syntax of the command) as

well as the resulting methods etc. - study the following carefully :-

The clearer version of the commands / script is show below :-

==========================================================

And the second half of the results output is shown in the following image :-

Notice above that all items/entries except two are Methods.

Lets try a few members ..................

Common Method - 'Substring' :

Yep! - the good old 'Substring' method - for accessing parts of any string, variable or literal.

We just can't do String manipulation without it, or indeed the 'Length' property.

==============================================================================

And now we can use the next short script by pressing 'F5' to run, or execute - check this :-

Yes, the above stuff works OK.

Now for some 'Length' information - or a Property member :-

And now we can use the exploration of the 'Length' property to try out ways of displaying text

and string data to the results pane / screen.

Below is shown the generating script as well as the resulting output details :-

Yes, it would appear from the above output that only line 8 is the way to achieve what we are after.

So to tidy this up for future use we get the next image :-

And now lets see Length in use within some meaningful script.

Checkout line 5 in the following image - we could not do without 'Length' to aid our scripting :-

PHH - 2nd. November 2015.


String to array

Well folks, its not every day that we get a chance to use the 'ToCharArray' member of the System.String

class. But we have a little project in hand which could do with its help and support.

First of all lets see what this member looks like in some useful script - see below :-

Yes, this above seems to work very well indeed.

By splitting up the String into a character array we can then reassemble it with concatenation, as

long as we get the order right of line 12 of the script.

Note the $char MUST come before the variable for the growing string.

Now then, in line with some earlier functions created for other sub-sections of these eNotes, let

us add the script to make some time calculations - check below :-

Well, for a string of this size it seems to compare very favourably with the rest of the alternative

functions. But we ought to make further tests with much longer input strings.

Strings to an Array of Strings :

Lets now have a little bit of fun, and play with string arrays.

Here is my first syntax - check it out :-

And now the alternative and more meaningful syntax - perhaps !?

Although this above is not any more 'correct' it does read easily and in a more understandable fashion.

At lease we can read that it is an array of strings.

And to prove it lets print the string values in a different way - all good practise for our scripting skills.

Okay folks, just as we might expect - BUT - look at the next image as we may not expect to have

this syntax work for us.

Check out in particular line 37 - see below :-

Although we think of a System.Array as being fixed in length, it appears that the ' += ' operator does

add an extra item to the array, each time we apply it.

If we try to do this ourselves then the code we may try is seen below - after it has failed.

Although an 'Add' method is offered by the intellisense, it does not work for us - check this out :-

Time to move on ..............

Quit while we are winning is another useful phrase - we have an easy way to add items to an Array.

I would guess that this will work for all Arrays, not just those of Strings.

*** Guess *** the PS engine is doing more behind the scene than we might at first expect. I think it is

doing so tedious work stuff to get over the limitation of fixed length arrays.

Finally study this :-

See you in the next sub-section ................

PHH - 5th. November & 3rd. December 2015.


String to Numerics - or Numbers from Strings

We need to look at the 'System.String' class for our own knowledge and understanding, and

find out how to do some converting - HOWEVER - there are other ways, possibly better, or more flexible,

when we look at the 'Convert' class in the next child section we will see a heap!

Here is what Help Viewer 2.2 has to say on the String class :-

============================================================================================================================================

Now then - we have made the classic mistake of starting with the string class just because we have a string value.

Have a look for yourself to see that there are few methods in String for converting as we require.

We are much better advised to start with the class of the target value - for once we have converted.

So if we wish to make our string into an Int32, we are better off thinking in terms of creating an Int32

from an input string value.

This means we need to search and locate the help notes on the Int32 class - check below :-

==============================================================================================

Now then folks, this looks a whole heap better as there are quite a few Parse and TryParse methods

within the class, we just need choose the one closest to what we have as input parameters, or values.

Check out these Methods :-

================================================================================================================================================================

Please bare in mind that other classes of numerics will also have similar Parse and TryParse static methods.

Lets now try out some script typing - check below :-

===============================================================================================================

And when we complete the text and run the script we see the following :-

And 'gm' or Get-Member shows us that we indeed have a variable of the type 'Int32' and the

output in the results pane shows us that it has the correct value.

Lets now try a few different overloads of this method - here is a more complex one :-

And we can now run the completed script to see what we get - study the following :-

Yes, we can supply a currency symbol in the input text and have it stripped out for the final value.

Lets now see if we can quickly move on to a different Type by just assuming that it has a full and

similar set of Parse and TryParse static methods.

Moving on to Decimal Types :

So then, lets cross our fingers and just go for it ;-0)

We are now trying a compound 'NumberStyles' parameter, and also I have split the long line by adding a

back-tick to the end of line 11 shown below :-

=================================================================================================================================================================

Please be fully aware that the operator has been changed from the .NET help notes of ' | ' to a ' + ' sign.

I imagine the pipe symbol was not a good choice for the PS syntax, so with use a plus sign / symbol.

I found this out by trial and error ;-0)

Now let us run the script section :-

Well, it runs and interprets without any red error output text.

Now all we need do is try to include a decimal point in our value - check below :-

Yep! - it seems to work just fine.

Now we are in a position to try a lot more stuff in various ways - we have the syntax and the ideas.

Finally, lets try one more example from the Viewer notes - check below to see :-

Yes we have converted "103E02" into '10300'.

Over to you - have some fun ;-0)

I am going for my tea ...................

PHH - 2nd. & 3rd. December 2015.


Convert - using the .NET class

Okay then guys, if you want to convert a value in one data type into a value of another and different

data type, then the 'Convert' class is your best friend.

It is a .NET class which is probably best used in our scripting, as opposed to our command lines.

Here is what Help Viewer 2.2 has to say :-

===========================================================================================================================================

So we need to use 'System.Convert' in our scripting square brackets - " [ ] ".

There are a huge number of STATIC methods to do the converting - below is just a few :-

====================================================================================================

Here is an interesting one :-

===============================================================================================================================================

And here is some general information about the class.

Obviously not all we would randomly try to convert will actually convert correctly, so we still need to exercise some care.

Check this out :-

==============================================================================================================================

I will leave it up to you to tray out most of this stuff, once I have given you a start by showing

some useful conversions below :-

=====================================================================================

There does seem to be some flexibility in the format of our input string, just keep away from

colons in the test strings - I get red error messages ;-0)

Here is a start :-

And now from separating dashes to separating commas :-

And what about a reversal of year, month, day ? See below :-

Please be well aware that you need to do some experimenting with the input string format as

it does vary from the .NET help notes.

This next example is one I had to work on a little before I got it to work - check below :-

[ .. here we have a full date and time as well .. ]

Okay then folks, I think it is over to you - I have done enough by presenting the class and its

endless possibilities.

Good Luck!

See you in the next sub-section ...................

PHH - 3rd. December 2015.


Formatting our Strings

PHH - 1st. Nov. 2015.


Simple numbers

Be aware of the 'Simple' approach - it can come back and bite us !!

======================================================================================

'Simple' is all very well, and having the PS engine do stuff automatically for us seems a good idea,

well at least at first. Then reality kicks in.

When it comes to variables my personal feeling, after using the .NET framework for so long, is that

we should be careful and thorough when we create any and all of our own variables.

Cast them correct right from the start - in our script section.

Now then lets look at some simple numbers and their possible use.

PHH - 2nd. November 2015.


More on numerics - Constants

===============================================================================

Here is an image of my first trials using the numeric constants mention above :-

PHH - 2nd. November 2015.


Numerical manipulation

Using the 'Operators' -as and -is :

Let us first do a few 'casts' while we create a new variable for ourselves :-

And if we really wish to know what type of data variable we have created we should use 'gm' / 'GM'.

Study the following image details thoroughly :-

And here is the example from the Jones and Hicks eBook :-

And changing things just a little we can now cast our answer, and hence our variable type, to a 'double' :-

And now a 'float' :-

Then a 'decimal' as seen below :-

And finally for now ant 'int64' - check below :-

PHH - 2nd. November 2015.


Converting

PHH - 2nd. December 2015.


Large numbers - and more

PHH - 2nd. November 2015.


Arrays, Lists and Collections ?

Here is a useful URL / link :-

http://stam.blogs.com/8bits/2010/05/arrays-in-powershell.html

Thanks to Mark Stam we can use some bits of his blog in this chapter on Arrays.

I will add a lot more of my own examples and explanation however - a perspective of the .NET coder ;-)

*** CARE *** The documentation on PowerShell can be confusing when it comes to lists

and collections.

Quite often in the web and eBook documentation we see the words 'list' and 'collection' used

in a most general sense.

To .NET developers using C# and Vulcan we usually think of collections as data types like in the

very helpful "ObservableCollection" - often used with MVVM apps.

We tend to think of lists and collections as data types or classes - so be aware !!

It would appear to me that in PS5 we have System.Array objects when we see lists being made

and processed. And then 'obviously' we spend some time trying to 'fight' the fact that System.Array

types are fixed in length, not naturally 'dynamic'.

We have to use and work in Arrays some of the time, simply because the 'cmdlets' and piping of these,

seem very often to produce arrays - which are fixed in length.

The fact that these list objects the commands produce have a 'Length' property tells us that they

are not 'collections' as .NET guys would know - variable length collections have a 'Count' property and

NOT a Length one.

So the basic simple summary is in 'PS5' to always think of 'Arrays' when we have multiple items in one variable.

The items in this variable name can be accessed using an indexing system.

The index is zero based, and negative values refer to counting back from the last element, -1 is the last.

So we can refer to the last element in two different ways - check below :-

The details of making and using arrays (in a whole variety of ways) can be found in the child sections from here

(in this chapter).

The Reality of the World we inhabit :

The world of .NET did not happen all at once, it evolved with time, and as such it has a 'History' and quite

a rich history at that.

It means that not all Namespaces were created at the same time, and not all data Types for holding lists

and collections appeared to us, the developers, at the same time.

So we the coder / developer guys are left with what may look like some confusion on our plates ;-0(

The easiest way I have of dealing with this is to try to get one (or just a few) ways of using collections

which apply generally to most (or all) situations.

'List<T>' is about 'as good as it comes' ;-0)

Oh! and just to possibly confuse things, 'List' and 'List<T>' are in different namespaces ;-0)

There is a good reason, but its not immediately obvious.

PHH - 4th. & 16th. November 2015.


String arrays

Well guys, lets get started, lets make some working script.

Open up 'Windows PowerShell ISE' ready for use - we are about to enter some 'script' text,

then test it out by running it.

We will be exploring the different syntax forms, as well as just getting stuff to work.

Syntax 1 :

[ *** I have called this '1' simply to differentiate from the second and third way of doing things .. ]

Here is our first example, the syntax is clear and clean, and it works :-

[ .. remember to 'save' the script to simplify the result pane output .. ]

Notice that in the above image we do get four separate string items, each has been displayed one

on a line, by the single command on line 3. We could have typed this at the command prompt just

as easily as running a typed and save script.

Below is the same command line text copied and run, one line at a time, in the console window.

Check this out carefully - note any small differences in colours and layout :-

Lets move on a step ............

==================================================================

Syntax 2 :

[ *** once again there is no significance in the '2' except for identification purposes ..]

Here now is a second and slightly different format. We need to be able to read and use the

different syntax forms, simply because we all will be reading scripts created by others, and we

all have our own favoured ways of doing things ;-) That's why we are called 'People' - "nowt so

queer as folks!"

In the following image note the included braces ' ( ) ', as well as the casting :-

There seems to be yet another version of the same syntax as seen below :-

=======================================================================================

We will examine later whether the above is doing what we think it should be doing.

But before that lets try a third syntax .............

Syntax 3 :

Lets now examine a third syntax option, check this out below :-

So lets now move on a pace, to see how to declare empty arrays ..........

Creating empty arrays :

It is not that clear at first as to why we would want an empty array, but we can explain that

later. Remember the array is our variable type - so our variable is an empty array.

If we try to make a zero length empty array with syntaxes 1 and 2 we can't.

The interpreter or parser throws an error unless we provide at least one empty Strings.

==============================================================================================

And now the empty String :-

Lets move on a step or two ........

Syntax 3 : (again)

Before we go to explore how to access and use the array elements, lets see how we can add

more elements to an already existing array.

Oh! - we can learn a lot from the following syntax example ;-)

Have a very good and careful look at this following image :-

Yes, above we have taken three filled and fixed length arrays and effectively added them together.

You can think of it as joining the three together, or something similar.

However, under the hood I feel that a four new array was created and the existing items (elements)

from the other three then copied into the new array - that's my guess ;-0))

Addendum :

PHH - 4th. November 2015.


Accessing our arrays

Well folks, we have a very useful example to look at now, this will teach us quite a few things ;-)

We are going to use the indexing way to access array elements - check out the details :-

On line 3 above we see that index ' 1 ' gives us 'Dick' and not "Tom", so we have an index base of zero '0'

and not one.

This is consistent with all stuff .NET.

However, the negative index is what we would expect, and so line 9 gives a result of 'Squeek'.

Just a thought about Don ;-0) Is this because we can't have ' - 0 ' ?

So indexed element -6 and also -2 are both of value "and".

The above image shows us some interesting script for us to think about.

Lets move on ........................

PHH - 4th. November 2015.


Some simple PS5 examples

Using 'Strings' :

PHH - 4th. November 2015.


Fixed length

*** Rule of Thumb ***

Fixed length array / list objects have a 'Length' property, whereas variable length list / collection

objects have a 'Count' property.

When we talk of arrays we are really talking about the class of type 'System.Array' and these objects

are of fixed length. Once they are made / instantiated, they can't have elements added.

If the syntax in PS5 looks as it another variable value is being 'added' it is simply the surface 'look' of

it, and in fact a new object is being created with all of the elements involved.

Lets do some exploring and experimenting.

Starting simply we can make an array like this :-

Yes, in the image above we have three elements and all are output to the display (results pane)

when we use the variable name.

Lets move on to finding the length of our newly made array :-

Okay, 3 as we would expect, and note we used the 'Length' property and not 'Count'.

So what if we try to increase the length of the array in a simple and possibly obvious way ?

Checkout the follow approach :-

Yep! - as we may have imagined things - 'Length' is R/O and a consequence of the existing elements.

It is NOT a way to increase the size of our array object.

So what if we try to use the 'Add' method which appears in the intellisense drop list ?

Study the details of why and how this fails :-

Yep! - we have a fixed size collection, so why we have 'Add' in the offered drop list I have no idea.

Now then, there are some simple ways around the fixed length restriction. Study the following details :-

Well folks, we have made a

PHH - 4th. & 16th. November 2015.


Operators : -join and -split

PHH - 4th. November 2015.


Variable (not fixed) length

Some common Types we can choose from :-

ArrayList, List<T>, ObservableCollection<T>

Stack, Queue, Stack<T>, Queue<T>,

HashTable, SortedList,

Dictionary<T>, SortedList<T>, LinkedList<T>, SortedDictionary<T>, HashSet<T>

===========================================================================================================

=====================================================================================================================================================

'Casting' comes to our aid (Help) :

If we have a fixed length array object we can easily create from this a new object which is of

variable length, simply by casting in the correct manner.

Lets start with a simple string array (System.Array type) and from this make a new ArrayList

object to which extra (further) items may be added.

As we 'Add' elements to the ArrayList the Count property increases accordingly.

Study the following image details very carefully, and thoroughly :-

================================================================

So in the above image we have used the array called '$my_Array' to create the ArrayList called

'$my_AL' and then added an extra string element of value "magic!" and the output the collection

as well as outputting the Count property value.

Variables Existing in Memory :

You may be as interested as me to find out just which variables are still resident in memory.

We say they are 'persistent'.

In the example I show, I have been using three tabs to explore and experiment with arrays and

casting etc., etc..

Check out the details shown below :-

Yes, it may surprise you that the resident variables and their values are from all of the

three Tab scripts which have been run.

If I now close down all the tabs and the PowerShell ISE instance we have open, then

reload the same three Tabs - without any script running / execution, then we see the

following details when we try to see existing variables :-

Notice above that the first attempt to list our own variables gave no results at all (not surprisingly) but

in order to prove to you that it was working I have left off the underscore for the second attempt.

So it looks as though all variables used in a PS5 'session' are kept in memory, and are persistent.

PHH - 4th. & 16th. November 2015.


String lists - converting all things to arrays

PHH - 4th. November 2015.


String lists - using the ArrayList type

==========================================================================

PHH - 8th. November 2015.


Generic Classes

*** NOTE *** It is helpful to remember that Generic Classes do not contain any STATIC members.

===============================================================================

Generic Classes are probably best typified by List<T>, Stack<T> and Queue<T>. There are others in the

same namespace called "System.Collections.Generic".

As well as a very useful class of "ObservableCollection<T>" which is in a different namespace to the afore

mentioned classes.

Lets use Help Viewer 2.2 from Microsoft to see some of the related entries - lets start with this below :-

================================================================================================================

And now having seen the 'OC' (ObservableCollection<T>) class we can move to the historically earlier namespace.

Check out the following details :-

=====================================================================================================================================================

And now to look at some Class details :-

==========================================================================================================================

===================================================================

======================================================================================================================================================================

PHH - 28th. November 2015.


Sorting Arrays in code

Okay the folks, so far with PowerShell work in these eNotes we have seen many examples of how to

use the cmdlet 'Sort-Object' (or the alias 'Sort') to good effect.

Here shown below, is a typical example - line 60 is where it all happens :-

======================================================================================================

So above we are copying a variable to itself after piping to the sorting command-let.

The results of just this sorting can be seen in the following 'GridView' auto-output :-

=================================================================================

Now then guys, we can also do some array sorting using the STATIC method of the System.Array

class.

In the following image we see that after the sort on line 60 we actually sort the array a further time

and into order A-Z (ascending).

Checkout below line 67 which does a .NET sort - notice how we access the Method :-

==========================================================================================

Yes, all is good - AND - we can compare the order of items shown in the 'VerbList' of the grid.

Now we see A,C,C,C .... in place of W,U,U,S .....

Here below are the important code details - line 67 is the line in particular. The sorted array is

still within the same variable :-

=============================================================================================

===============================================================================================================================

PHH - 28th. November 2015.


Sorting typed Lists in code

Okay then folks, let us consult the Help Viewer 2.2 from Microsoft, which came to me with Visual Studio 2015.

The following image is of the Search for "System.Collections.List class" :-

====================================================================================================================================================

PHH - 28th. November 2015.


Chapter 5 - 'Objects'

We need to get it firmly into our heads that everything we deal with in the PowerShell system is

an 'Object'.

Although we may see some text in a Console pane which looks like old DOS syntax, we are always

working with 'Objects' And as such with Properties and Methods as well.

In fact any old fashioned DOS syntax is just that - in reality it is turned into PS object stuff immediately,

by the Interpreter.

So to summarise, built-in PS stuff is all object based, and all our scripting is based on .NET classes

of objects. 100 % objects !

To me and any .NET guy this is nice to know and makes our task of learning PowerShell so much easier.

However, there is a lot of stuff in published material which seems to labour the point of using objects and

even what they are - as if they appeared yesterday.

I do wonder that even the PS gurus and not that comfortable with objects at times. This is why I have had

to put a LOT more of my 'stuff' into not just custom classes, but also using more complex .NET classes

as well. Here I refer to List<T> and ObervableCollection<T>, as well as ArrayList.

It was difficult to find out the correct syntax for creating our own classes, so this tells you what I say above

is likely to be right.

*** Good News ***

There are definite benefits for an object based management system, and to have moved away from any form

of text based input or system, even in part.

Lets move on a learn some object 'stuff'.

PHH - 30th. October 2015.


Objects within the PS 'cmdlet' system

Okay then folks, lets start out right away to demonstrate that 'Objects' are at the heart of even

the oldest looking of commands.

Lets try this old 'chestnut' :-

Do you think it is DOS ? As in MS-DOS of the early '80s ?

Well then look at this piped command and think again :-

The cmdlet 'gm' is an alias for 'Get-Member' and as you know classes have members.

The class of items returned by the command is shown to be "System.IO.DirectoryInfo".

If we launch Help Viewer 2.2 from Microsoft we can search and find this class - it is in even the

latest .NET framework of 4.5 - check below :-

==================================================================================================================================================================

Now then guys, we can type the full PS syntax without any aliases as seen below :-

And if we look closely at our results for 'gm' (Get-Member) we see that there is information (results)

for two classes, the other being for files as opposed to folders - check below :-

And once again we see it is a class from .NET as seen in the Help Viewer display below :-

[ .. note this is for framework 4.5 and 4.6 .. ]

================================================================================================================================================

Okay then folks - so files are objects and folders are objects, as seen by our commands and scripts

of PS5. There can't be anything more basic or fundamental than that !?

And remember - DOS has absolutely nothing at all to do with this - just the old syntax still does something

close to what it used to look like 'way back'.

We can go a little further with this ..............

Lets us study the top of the results for directory / folder :-

Notice above that we have a 'Mode' column / property. It would appear that 'd' is for directory.

And now below we see some other entries, which look like files - is 'a' for archive ?

And also part way down this list we see this below :-

The 'Users' directory / folder is most likely to have an attribute set as Read Only - so is this what

the 'r' represents ?

We need to examine the 'Attributes' property of the 'FileSystemInfo' class.

Here is a start from the Help Viewer database :-

==========================================================================

And this is helpful for us to understand further - study the following :-

==========================================================================================================================================

There is an enumeration in the .NET framework which seems to be being used - checkout the next image detail :-

=================================================================================================================

And I feel that the 'Mode' column we saw earlier is made up from the logical settings for 6 of the above 7 setting values.

The first position in Mode seems to be a Directory (or not) and the second position / place probably Archive.

Check below :-

And also this :-

And then another :-

I am now guessing that the 'S' is for system, and ' l ' for locked in some way ? Need to investigate that further.

Getting back to the thread of this sub-topic, its all about Objects, Properties and Methods - or generally

speaking 'Members'.

Forget DOS and I also suggest you forget the older syntax, even though it may still work.

Get used to the new PS syntax, and even avoid Aliases - since we have intellisense who cares about how

much typing we have to do or not do !?

Final Points about Objects in PowerShell :

Look back at "Chapter 1" about Pipes, and pipe-lining.

If we are to construct pipelines then we need to consider carefully the objects flowing from one cmdlet to the next.

Remember that pipes are VERY commonly used in PS commands. And that data flows from one cmdlet, into the

next one in the pipeline.

If we don't get our data Types right for the cmdlets we are using then we will not get the results we expect to see

displayed in the console results pane, or indeed the 'GridView' tool.

When using PowerShell we should NOT shirk away from actually going to find out just which types of object our

data is stored in - be proactive, go and find out !

Also be aware that the PowerShell engine tries its best to convert (or cast) output data objects into suitable

input data objects for the cmdlets involved in a Pipe - this too may give us something we do not wish for. So

check first is the mantra.

There are a bunch of cmdlets which seem to be more general than most, in that they accept data as plain old

'Objects' - a very general class indeed, in the .NET framework. The name even gives them away - check below :-

Getting the search string pattern correct (as above) is important / crucial - here are the results :-

It would appear that these work with the Type 'Object', and all but the 'New' cmdlet actually accept a bunch

of Objects. When I say 'bunch' I mean an array of Objects.

Lets see more detail for the commonly used 'Sort-Object' cmdlet - check this out :-

Notice under SYNTAX that the second option is an array of Objects.

We will examine and explore this cmdlet further in the relevant section in these eNotes.

This leaves us wondering just what Type the output is !/ My guess would be another array of Objects.

Why ? Simply because we often in a pipeline use one of these "-object" cmdlets after another.

Check this out as an example from elsewhere in these eNotes.

At some point in the pipeline I have a different type of object and Name becomes something it was not

at the start of the command line.

In the above image we see the command has four such 'Object' named cmdlets, one after another

in the pipeline.

If we comment out some script as seen below, we can then see what our property / columns are :-

So we can now correct our original script and although it is a bit of a silly example generally,

it does demonstrate what we are trying to see.

Study this below :-

Now that makes sense to me - hope it does to you.

Time to move on, see you in the next sub-section ......................

PHH - 2nd. December 2015.


Objects created in our Scripts

Objects are instantiated 'things' made from the pattern or outline specified in defined Classes.

There are many types of possible Object when we use the .NET framework.

In PowerShell commands, and scripts, we can use all of the .NET classes, and so we do need to

know how to access them.

It is always helpful to how to find details of a Class using the Help Viewer desktop application.

In the following image we have searched of the 'DataTable' class - and can see which assembly

and Namespace it is in - check the details below :-

=========================================================================================

Moving on, lets consider Objects within the use of PowerShell ............

==============================================================================

*** IMPORTANT *** You MUST get this into your head, I have been thinking on it for a while !

"Everything in PowerShell— and we do mean everything —is treated as an object. Even a

simple string of characters, such as a computer name, is considered an object."

I am sorry the English is not better, the above should read that everything IS an object, and not just

treated like one.

If we look at what some call a simple string, then it has "Properties and Methods". And we all

know that having "Ps & Ms" as members more or less defines and Object !

Checkout the following example, in which we see both a Property and a Method :-

Line 1 shows us not to try out old DOS commands - just forget DOS !

Line 4 shows the 'Length' property of the String class, as well as the ToString method.

Line 5 also has the ToString method.

*** Be Aware ***

Just because we type in at the console cursor quite a bit of text should NOT lead us to think

that PowerShell is in any way text based - it is not, it is definitely firmly object based.

Since a Class is just a definition of how to construct, make, or instantiate an object of that class,

then at run time, when the app is running, we have all objects in memory, of many Types.

Type is applied to an object when telling of its class. So we can have an Object named 'FancySports'

and it is of Type 'MyCar'. The class 'MyCar' was defined by me.

Think of a Class as being like the plans for a building, then the building itself is the Object, the

Class is the plan from which it is made.

Enough for now, most .NET guys know all this stuff and use it every day.

Before we move on lets see how intellisense shows us details of the Ps & Ms of the String class.

Checkout these details :-

========================================================================

Above we see only one Property - that of Length.

And here are some more Methods :-

=================================================================================

In fact the String class has a lot of useful methods, and these are all used extensively

when we come to string handling and writing scripts.

PHH - 2nd. December 2015.


Variables as Objects

Some variables are 'value' types and some others are Objects.

Very often Objects have properties which are 'value' types.

In the modern world of ICT we should use objects all of the time, AND, much more than

we used to a few years back,

There are definite advantages to using objects whenever we can.

If you wish to argue the point about the above then you are doing it all wrong, and

have definitely missed the point of all this stuff ;-0)

So even something as simple as that shown below is VERY much bound up in objects,

classes, methods and properties :-

It doesn't get simpler than above, just far more complex, and many more objects ;-0)

Lets now look at a few more examples to show us the diversity of object Types.

PHH - 17th. November 2015.


Objects returned from Commands

PHH - 17th. November 2015.


Objects made from our own scripting

PHH - 17th. November 2015.


CARE while making comparisons

In the 'Functions' appendix section we ended up with a final test shown below.

As a trial we were changing the logical and conditional check shown on lines 26/27.

Instead of looking for empty arrays as those with zero length, we tried to compare the array in focus with

a new array of zero length - as @().

At first glance this seems a reasonable test, and thing to do. BUT - once we think of the comparison as

that between actual 'objects' then we quite simply know that the objects are two quite separate ones, and the

test will therefore fail.

Yes, we are comparing two empty arrays, but they are NOT The same arrays - different objects.

Think on this carefully, and LEARN ! ;-0))

PHH - 6th. December 2015.


Chapter 6 - 'Classes' & 'Structures'

If we are to be dealing and working with Classes then we do need to know how best to find

details of existing .NET Classes in the Microsoft documentation.

Here is a search in Help Viewer 2.2 (see appendices for this) where I am looking for the

'DataTable' class - check this out :-

=========================================================================================

It is most helpful to be able to click the items at the Left Hand Side (LHS) and then get the

details of Assembly and Namespace showing in the RHS details pane.

Structures and Classes :

To all intents and purposes, 'Structures' can be thought of as lightweight Classes.

Commonly used structures are 'DateTime' and 'TimeSpan', we will study them later in this chapter.

=======================================================================

Our own Classes - defining what we want ! :

When I wrote my first successful class called 'Car' I found the following web article most helpful,

in that it gave me useful clues which eBooks and other stuff do not, at that time.

It opened the door for me on Classes of my own, and the working Car sample class is now

to be found in the 'Our own ....... ' section of this chapter.

http://trevorsullivan.net/2014/10/25/implementing-a-net-class-in-powershell-v5/

======================================================================================

PHH - 30th. October 2015.


'Random' class

In .NET we have the following class for generating Random numbers and the likes.

Study the details see below :-

=================================================================================================================================

Although we can use the above class in C# and VN in our .NET coding to good effect, it is actually

much easier in PowerShell to use one of the 'cmdlets'.

Since Microsoft has made the effort to create 'Get-Random' then there must be a good reason to do so.

So in my book - just use the cmdlet and get on with life ;-0)

Here are a few visual tips on its use :-

Typed at the console input command line we get intellisense to guide us, as seen in the above image.

Now lets see how we may use it in our scripts - check this out :-

Here we are using the cmdlet in its simplest and easiest form - typed input and nothing else.

Okay guys, above is okay but we can get the ISE to do more to help us - see the following 'Commands' box

which prompts us for some extra inputs - study carefully :-

======================================================

The above seed gives us the same random number - if the seed is kept the same.

Maximum and minimum can be varied to suit our needs.

Here is what we get after clicking (selecting) 'Insert' :-

After the insert I have pressed the return key (enter) and see this below :-

And with another and different seed value we see the following in the console results pane :-

Now lets try another and different range - from 10 to 25 - see below :-

And once we have typed by hand the new property values, we can press the return key :-

And the resulting random number is 13.

We now ought to be able to write a script which generates a whole sequence of random numbers

and adds them to a list for string and display purposes.

The .NET way - Objects ! :

Take a look at this possible 'scripting' approach to get a random number :-

PHH - 1st. Nov. 2015.


'Math' class

Now then .NET guys, you will know the 'Math' class from your work with .NET framework and coding applications.

So we need not explain too much, just show how to use Math and its STATIC methods (and a couple of STATIC properties)

in PowerShell scripting.

Here is what we see when we use Help Viewer 2.1 to do a search for us :-

===============================================================================================================================

So the Math class is in the System namespace, which is not really a surprise ;-0) Being so fundamental.

Lets take a look at a bunch of the methods on offer :-

=============================================================================================================================

And a couple more of what we can easily use :-

=============================================================================================================================

So lets get to grips with all this and give it a go - lets try the square root STATIC method.

[ *** Remember *** that static methods are akin (like) to using functions .. we don't need to instantiate .. ]

Okay then, above we get a suitable answer output - but do we need the full namespace in the [ ] 's ?

Before we do a check on that, lets see the intellisense support 'in action' :-

So in the next image we see a shortened use of the namespace (as 'System' should be default, as it were)

as well as us trying out the 'Truncate' method - study carefully :-

Seems to be working okay. However, we must use [Math] as a minimum namespace.

Lets try another pair of static members - methods for 'ceiling' and 'floor' - check this out :-

Good Example :

PHH - 1st. Nov. & 12th. Nov. 2015.


'DateTime' and 'TimeSpan'

Any guy familiar with .NET coding will be well aware of the two structures 'DateTime' and 'TimeSpan'.

Folks often misguidedly call them classes, when in fact they are structures. In reality to most guys

it makes little different.

I won't make any effort to discuss these structures in detail, but will show how to get the syntax right so that

we can use them to good effect in our scripts.

Here is a screen shot to show how intellisense may be invoked by us while typing in the scripting

pane of ISE :-

And now we can see in the following image how to use the STATIC property of 'Now' at the start

and end of our script, to allow us to be able to calculate a time difference, in a TimeSpan variable.

Generally speaking, a TimeSpan value is the sum or difference of two DateTime values.

Check this out carefully :-

*** CARE *** These different properties are NOT the whole value in the specified units.

To see how they are the parts and not a 'total' value in the units, check this out :-

This you may say is NOT surprising, however, it is more likely to catch us out when we are using

'TimeSpan' values.

Let us adjust a script I have to see what we mean, and what we can see.

The script forces a Windows Defender scan of the 'quick' variety - check the details :-

From the above timing values it would appear that the 'Ticks' value is a total measurement.

However, the other three we see of Minutes, Seconds and Milliseconds are just part values.

We can read the Ticks from the left hand side as 240 seconds - or 4 minutes, 2 seconds, and the 160

milliseconds - this is also obvious in the last line which is the full span value as a readable format.

Since all this stuff is simply .NET we can then move on ................

See you in the next sub-section.

PHH - 5th. November 2015. & 11th. November 2015.


Our own 'new' Classes - defined and used

Thanks to the help from Trevor Sullivan's web article :-

http://trevorsullivan.net/2014/10/25/implementing-a-net-class-in-powershell-v5/

Oh! as well as a short video clip from Ed Wilson, the Microsoft script guy.

I can't quite understand it, as Ed Wilson is a top Microsoft guy and yet his video clip seemed to

miss out a few 'chunks' of necessary script and explanation !?

Maybe Ed Wilson is not a teacher :-(

Here is an image of some small, simple, but good success ;-0))

Note in the above image, lines 10 and 11, with closing semi-colons - these are not really necessary.

The ' ; ' (semi-colon) is just required to separate multiple commands on the same line.

Let us now consider an improved version of this same 'Car' class, which has a lot of multiple lines

with the use of such semi-colons.

*** please NOTE *** I am not a fan of such scripting style ;-0((

And if you prefer to see the updated and upgraded 'Car' class without any semi-colons, then

here is your chance - study the following image details :-

========================================================================================

And YES - it still works, as well as giving the same output - check below :-

Okay folks, enough for now, lets move on to some child sections of this sub-section where we will

study Constructors in Classes, as well as Properties and Methods.

We will look at STATIC Methods and Properties too.

PHH - 2nd. November 2015.


Our own Constructors

Okay then guys, just so we can "see the light" about making our own Classes, and their Constructors,

lets create and define our own new class called "LightBulb". We will give it a few simple properties.

Check out these details - see below :-

===========================================

And even some more images of intellisense at work :-

=========================================================================

Completing the script for a Construtor-less class we can then run it as seen below :-

Yes, that is right, we do not seem to get any results in the console pane.

Lets now improve that by adding an extra simple line at line number 17 - check below :-

Line 17 produces the default display for an object of type 'LightBulb'.

So line 10 shows us instantiating to make a 'LightBulb' object, even though the defined class as it

stands does not have any Constructors defined.

PHH - 2nd. November 2015.


Our own Properties

Okay folks, every Class or 'Type' needs to have Properties and Methods, as well as its own

Constructors.

Now that we looked at Constructors in the previous sub-section, lets now move on to looking

at Properties within our own classes.

Remember Properties are, or hold, 'values' whereas Methods are 'actions', or effectively a set of

instructions.

So lets look at some values for our 'LightBulb' class. We can start be viewing the Type definitions :-

===============================================

Above we see that our simple LightBulb class only comprises of Properties. There are five

Properties two of Type string, two of Type int and one datetime. We can have more complex

Types if we so choose, and we will see a good example later in this sub-section, just below in fact.

It would appear that we don't need to declare an empty Constructor, and later you will see that

we can still instantiate even without one.

Now let us see in the following image the Car class definition, which includes two Constructors

as well as six Properties, one of which is a complex Type of class 'LightBulb' :-

And now we need to see how to access the new Property once we have an instantiated object.

In the following image check out line 39 in particular :-

And YES, the answer should be 'Phillips'.

Notice that the access to the 'make' Property of the 'bulb1' Property of the 'my_Car1' variable

is done through points ' . ' and not double colons.

Don't panic about this we will get the feel in time, and with practice ;-0)

STATIC Properties :

Okay then guys lets look back at the syntax of the only STATIC Property we have defined up

to the present moment in our eNotes work.

Here below in line 6 is the Property I am referring to :-

=================================================================================

Let us now see what the syntax needs to be to make it accessible to us - check out below :-

=============================================================================================

So you see above that we use the double colon as our access operator / symbol, and here is what

Jones & Hicks have to say :-

==========================================================================================================

So lets see this in action in our script - check the blue results pane image below :-

And before we look the next section on Methods, lets see how the intellisense looks when we

try to enter some relevant script in the ISE editor pane - check below :-

==================================================================================

There is not a lot on offer in the drop list, simply because the Class is so simple.

Lets see what we get for our other Class, that of 'LightBulb' - check below :-

====================================================================================================

Above we see that four Methods are available to us, but only one we created ourselves.

Note there are no STATIC Properties available in this class.

Changing STATIC Properties :

Before we get into a discussion on this topic of changing STATIC Properties from 'outside',

lets see the results of an experiment - see the following details :-

Yes, the way it stands it looks like we can influence things from outside of the Class script.

And finally, some more to get your head around - study this below :-

Time to move on ...................

See you in the next sub-section.

PHH - 3rd. & 14th. November 2015.


Our own Methods

Okay then guys this sb-section is easy enough, we just need to see and learn the syntax required

for us to define our our Methods within our own business classes.

We obviously also need to know how to call and use such Methods, and to have Methods both with

and without input parameters.

I think we have already seen a STATIC property, so we will extend our knowledge to define/make and test

a STATIC Method as well.

Let us see how our simple class called 'LightBulb' looks once we add a suitable and simple Method :-

=========================================================================================

All the above new Method does is to return a String made up from the values of two of the Class Properties.

Now lets see how to call this Method after instantiation. We will call the Method before and after we have

assigned values to the properties.

Check lines 29 and 36 below, as well as the results in the blue console pane :-

Notice that at the top of the blue results pane we get an output of 'dots' or 'points' simply

because this is the default assignment.

Once we have made more meaningful assignments we then get 'Phillips small' as the output

from our called Method. Just as we would have expected.

Lets move on, we need some input parameters .......

In the following image we see a newly defined Method called 'TotalPower'.

This new Method takes one parameter of type 'int' - which is actually 'Int32' I believe.

Check out the syntax on lines 20 through 24 in the image below :-

================================================================

So then folks, how do we call this Method, once we have instantiated, and gotten an object ?

Checkout line 44 in the following image, from where we make the call :-

The above output of '156' is actually the value returned by the called Method.

To make it clear to you - image shown below has the Method call highlighted :-

==================================================================

Okay then folks, so far so good ;-0)

Now lets look at a STATIC Method ................

STATIC Methods :

Okay guys, back to the STATIC variety of our members ;-0)

Having seen STATIC Properties in action, lets now see what the syntax is for us to create

and use STATIC Methods.

In the following image we see our first simple attempt at a STATIC Method - check it out :-

The above script and output is just part of a larger example, we just need to focus on lines 33

through 40, as well as the first line of the results pane.

But because of a few issues we need to improve this script and to get True / False output

instead of noughts and one.

Below is my improved version - I have learned a lot in doing it - more later on that :-0)

If we don't cast our variables we either get 0/1 output or an error message when we try the

'ToBoolean' method on the result variable.

We can remove some of the 'casts' to clean up the script - by doing the clean-up either in

the STATIC Method or of in the calling script in the general body of the script.

Lets see how both work - I prefer the casts in the Method - closer to the source of the data.

Check these different ways :-

And now this below :-

Okay, both work, its up to you to choose.

Just be aware that I spent quite a while trying to solve this in a different way,

and failed miserably - trying to use ToBoolean(). So take CARE !!!

Then, in messing around I found that this works apparently OK !?

There seems to be things happening behind the scenes of which I am not totally aware.

So to be safe, make your own casts, and cast more than less ;-0)

Good Luck.

See you in the next sub-section ....................

PHH - 2nd. & 14th. November 2015.


Collections of our own Class objects

Okay then folks, lets use this short sub-section to show how we can use ArrayList collections

to hold a number of items of our own classes.

First we will see an image of success - below we see three items in the collection being accessed

by index and certain chosen property values being displayed in the results console / pane :-

Let us now see the script which produced this and how the properties were set before the items

were placed into the growing ArrayList object - check the full details below :-

For some reason we get displayed the index of the newly added item - must be just how the scripting

system works !? We will discover in good time no doubt ;-0)

Lets now try to make a strongly typed List - one where we declare the type of each array / list item

to be stored within it. And remember, ONLY items of the stated type can be stored and accessed.

Lets make a List for Car type objects, and store a few such items, similar to the way we did for the

NOT strongly typed ArrayList.

Check out this below quite carefully :-

Now then, for some reason we do not get the index displayed in the results pane - as we have

previously had done with ArrayLists.

I will leave it up to you to try out a typed 'ObservableCollection' object and add items to that.

See you in the next sub-section .....................

PHH - 14th. November 2015.


Scope of Variables, Functions etc.,

This is going to be a difficult section as I don't really feel I know what is going on.

Usually we get a feel for things like scoping in a language, as we experiment and explore the syntax etc..

But with this scripting in the PowerShell interpreter, it seems as though I will need to focus on scoping

quite seriously, and make many more tests and checks.

The good news is that we can easily make progress with PS5 and get good looking results, without having

to worry too much at all about scope of Variables, Functions and the rest.

However, if we are to develop and start creating scripts to be used from command lines, and from within

other scripts, we DO need to know how scoping works.

The web and eBook material on scoping seems poor and thin on the ground.

That said, lets get to it and learn ;-0))

==========================================================================

*** CARE ***

What may confuse us C# / VN .NET developers is that scoping is done differently it would seem to

what we are used to in .NET coding.

==========================================================================

This may help us a little :-

"A scope only lasts as long as needed to execute whatever is in the scope.

That means the global scope only exists while PowerShell is running, a script scope only

exists while that script is running, and so forth.

Once whatever it is stops running, the scope vanishes, taking everything inside it with it.

PowerShell has some very specific—and sometimes confusing—rules for scoped

elements like aliases, variables, and functions.

However, the main rule is this: If you try to access a scoped element, PowerShell sees

if it exists within the current scope.

If it doesn’t, PowerShell sees if it exists in the current scope’s parent.

It continues going up the relationship tree until it gets to the global scope.

It’s easy to let this scope stuff confuse you.

You can avoid confusion by never relying on anything that’s in any scope other than the current one.

So before you try to access a variable within a script, make sure you’ve already assigned it a value within

that same scope.

Parameters in a Param() block are one way to do that, and there are many other ways to put values

and objects into a variable."

Here is some more possibly helpful stuff - still needs clarifying in my opinion :-

PHH - 14th. November 2015.


My own 'VerbGroupItem' class

Okay guys, lets start with am image of what we are after, when we use and deploy our new class.

Here is an auto-generated GridView produced by the cmdlet 'Out-GridView' :-

=====================================================================================

In the above image we can see that we have three columns which represent three different

properties in an object of type 'VerbGroupItem'.

This class is one which I designed and created, simply I wished to have one property which was a

typed list, holding a variable number of items for each instantiated object.

It seems to work just nicely ;-0)

So let us now look at the script / code that exists for my new class :-

============================================

In the above image we see line 6 is the 'empty' Constructor, and that lines 3,4, & 5 are

the property declarations.

Note in particular line 5 which shows an array of String type items.

============================================================================

PHH - 28th. November 2015.


Chapter 7 - 'Scripting' - getting to grips with it !

Appendix 'I' has some useful sub-sections on saving scripts, as well as using and running

already existing ones.

I suggest you study Appendix 'I' later.

Here in this chapter we will deal with the content of scripts and other more general issues,

like when and why we need to use scripts etc..

PHH - 30th. October 2015.


Our first simple Scripts

PHH - 31st. October 2015.


Using 'Get-Member'

The 'cmdlet' (said 'command let' ) we will use in this sub-section is named "Get-Member".

Before we try a one line Script, we need to know that the name of my PC platform is "BIG-T", which

means for me the big or large tower desktop machine.

In a new tab within the ISE app lets type the following :-

With even just one line in the script pane we can run it using the green arrow icon see below :-

=============================

The results appear in the console pane and are shown below :-

We get a long list and the end of the list is like this seen in the next image :-

Please note that many of the common 'cmdlets' have a shortened version, such that 'Gm' can be used in place of 'Get-Member'.

Here we can demonstrate this - see below :-

PHH - 1st. Nov. 2015.


Using 'Get-Process'

PHH - 1st. Nov. 2015.


Closing desktop apps

PHH - 1st. Nov. 2015.


Using 'Get-History'

PHH - 1st. Nov. 2015.


Using 'Get-Command'

PHH - 1st. Nov. 2015.


Using 'Get-Printer'

Okay then guys, lets go for using an obviously helpful 'Command let' and use the one for printers.

We can use the 'show Commands Add-on' icon at the top of the screen in the menu/icon bar :-

==================================================

Or even the 'Show Command Window' as see below :-

========================================================

And in the new pane for Commands we can search / filter for 'Get-Pri' to see what we get.

Check this out carefully :-

==========================================================

If we edit our script pane and comment out the existing 'process' line we see that Intellisense does

come to our aid to help us on our way ;-0) Check below :-

So we have a few ways of searching for 'cmdlets' and selecting suitable ones for our needs.

Let us now run the simplest script based on 'Get-Printer' - study the following image :-

Please note that depending on how wide we set the main app window, the output text is

adjusted to suit the setting.

So that if we make the above window narrower then we get less output detail - check carefully below :-

Yes, rather surprisingly, the text output lines are truncated part way through the 'DriverName' column.

Lets move on ..................

Going a Step Further - Counting :

Although there are a few ways to see how many Printers we have installed on the "BIG-T" machine of mine, we

can write some script lines which make us all feel quite comfortable - yes, program code ;-0)

Study the following thoroughly :-

Above I first cleared the results console pane with the 'wiper' icon in the menu bar.

Yes, the little greeny coloured icon which looks like a 'T' character on its side, is actually a hand wiper blade

like the ones we use on windows and shower doors in the bathroom.

Then I ran the script by licking the green arrowed icon - you can use 'F5' if you are an old codger !!

Now then, does the answer / result of 11 make any sense at all ? To know that we need to see what the

Windows 10 management GUI stuff gives us - check out thoroughly below :-

=================================================================================

Check the names with those shown in the image two above.

Now folks, lets do a better (more modern) way of finding the number of Printers.

Lets find out the total of the collection we have at hand - yes, 'Get-Printer' gives us a collection of items.

Check this out for details :-

And to tidy it up even more, and get our output lines more readable, see below :-

Notice in our small and simple scripts the red items are variables, and the '$' sign indicates this.

So our declared variables are :-

$Number, $MyPrinters, $Printer, and $PrinterCount.

I will leave it to you to find out what data types these are !?

Time to move on to another sub-section. See you there ........................

PHH - 1st. Nov. 2015.

Addendum :

Here is a clue as to some of the data types - check the next image out carefully :-

Yes, interesting isn't it ;-0)

We did say it was going to be objects all through PowerShell.


A more advanced Script

PHH - 31st. October 2015.


Nested ? Scripts

PHH - 31st. October 2015.


Multiple Scripts, one console pane

PHH - 31st. October 2015.


Selecting and Running a Script - manual and auto

Lets start from the successful result (or conclusion) point of view, probably the complete opposite

of where you thought we would ;-0)

Running Windows Defender :

Lets look at a 'PowerShell' open pane which has content, and which closes immediately we press

the enter key - check these details :-

Running Windows "Media Player" :

=========================================================================================

Microsoft's Notepad :

WinRAR & '7Z' :

"C:\Program Files\WinRAR\WinRAR.exe"

"C:\Program Files\7-Zip\7zFM.exe"

PHH - 11th. November 2015.


Managing our 'Scripts'

PHH - 4th. November 2015.


Log files for Scripts

==========================================================================================================================

http://9to5it.com/powershell-logging-function-library/

==========================================================================================================================

PHH - 23rd. November 2015.


Chapter 8 - 'Scripting' as programming

my notes :-

<< Conditional Statements

Switch Statements

Looping :

for

foreach

while

do ... while

Flow : break, continue >>

========================================================================

To put things simply, when we write a 'Script' to run in PowerShell we are effectively writing program

code - as we used to know the activity ;-0)

So although we end up with a bunch of commands, then 'Script' can be thought of like an app or

program.

Be aware that the script runs just as if we have typed each line at the prompt in the console pane.

So there is no fancy code (or script) compiler.

It would appear as if the PowerShell has an 'interpreter', this is like a simple compiler, but it works

on one line at a time - one command line gets parsed and run, one line after the previous line.

One way to prove this is to see when the red error text is printed in the results pane, as well as

where it is placed compared to the genuine white text output.

A compiler will not run if there is an error in/with the script / code.

An interpreter runs each line and produces genuine output, and ONLY when an error occurs in

the line in-focus does it produce and print out the error text.

Then it keeps on running the rest of the script commands, and producing results.

We also need to realise that script lines entered and run in the console window may not have the

benefits of an IDE tool, such as ISE or PowerShellPlus, when there is intellisense and pre-parsing

carried out on entered text - into the editor pane.

The best advice I can give is select a tool (start with ISE) and then get to know how it operates, and

from experience of trying stuff out, just how it seems to work for you.

Personally I like drag and drop with mouse pointer, just love it in VS as well.

Horses for courses - personal choice, all that sort of thing ;-0)

Get up and go for it !!

Let's move on .......................

PHH - 4th. November 2015.


Commenting script

Jones and Hicks have this to say :-

==============================================================================================

Buy a copy of their eBook, it is well worth the money - its a good reference to have.

Moving on ...................

# - As Script comment and explanation :

Lets see what some in-script commenting may look like :-

==============================================================================

However, we can also use the block commenting using ' <# ...... #> ' enclosing symbols, or characters.

Here is a real example from their eBook :-

......................................

......................................

......................................

=======================================================================================================

The actual commented block was MUCH longer than is shown above.

Personally I like as little commenting as possible, and much clearer script and careful choice of variable names,

and naming of Functions etc., etc..

# - As part of Testing :

This is the part I think many of us will use most, at least while we are learning 'PowerShell' and scripting.

By this I mean we will place either a single hash sign on a line, or a block 'tag pair' around existing

or typed text in the script.

Often we wish to just temporarily remove some commands, before adding them back later - after

doing some testing. Below are a couple of examples.

A block or body of script lines :-

===============================================================================

A single line or last part of line :-

=============================================================================

I strongly suggest you try out this stuff as you explore PS5 - learn it 'on-the-fly' as it were.

Lets move on a step or two .............

PHH - 8th. November 2015.


Declaring Variables - where, why and Scope!?

There is some VERY useful detail on variables in Chapter 3 - it's second sub-section, or thereabouts.

Read the earlier section before studying this one.

PHH - 4th. November 2015.


'Splitting' up very long lines

Getting around VERY long lines in a Script :

Where we split the lines - at the 'piping' symbol :-

======================================================================================

If we have a command line which includes 'piping', then we can split the line after the 'pipe' character

as we see in the above image.

=======================================================================================================================

PHH - 8th. November 2015.


Operators - simple and comparison

PHH - 4th. November 2015.


'Ifs' - no buts !? (conditionals)

PHH - 4th. November 2015.


the 'Switch' statement

The basic "Switch Statement" :

The switch statement is similar to a 'Case Statement'.

It enables us to write a script that can choose from a series of options, but without requiring us to write

a long series of 'IF' statements.

PHH - 11th. November 2015.


Looping - many ways !?

PHH - 5th. November 2015.


for statement

The 'For' or 'for' loop :

*** Remember *** case does not seem to matter in PowerShell syntax, but it is good to follow what

others seem to use in eBooks and experienced web articles.

So we will use 'for' - as well as 'foreach', while' and 'do' ...........

Often us guys say a "For ... Next" loop, simply because older languages used 'Next' as delimiter of

the 'For' line - thus defining a block or section of code.

Now we have 'For ... Curly Brace' on that way of thinking ;-0)

We will stick to using 'for' in our example scripts.

Lets see a For loop in working script - check the following details :-

[ .. note how semi-colons are used for command separation .. ]

====================================================================================================

Now then folks, I suppose you want some proof that this works - well below is my proof to you :-

===================================================================================================

Okay then we have 'lift-off', but what about a cleaner look in a more traditional way ?

Lets bring back ' i ' and all will be forgiven ;-) - see if the next image suits you ? :-

===================================================================================

PHH - 5th. November 2015.


foreach statement

Okay guys, 'foreach' is certainly a .NET thing and I like it a lot.

It is built into the compiler / interpreter as a way to easily access and process 'Collections'.

Here is an image of some simple enough script, but it does a useful job, as you will see in a moment.

First, examine the following :-

==============================================================

And here is the result of running the fuller version of the script using these lines :-

And now you may well wish to see the function which is based on the above 'foreach' section.

Check out the following details carefully :-

Yes, the above script is nice enough and does the job just great.

Lets move on and see some other ways in which 'foreach' can be used.

'foreach' with Get-Process :

http://powershell.org/wp/kb/foreach-vs-foreach-vs-foreach/

PHH - 5th. November 2015.


while statement

Okay then you guys, a good example from someone else should never be ignored ;-)

Here is one which is in the eBook by Lee Holmes (see Introduction section of here).

In the following image we see our first 'while' loop, or statement - check it out :-

As well as seeing how to get user input read from the console typed input into our running script,

we can also see that the conditional comparison is carried out before the body of the statement

block is executed.

Therefore, if the condition is found to be false the rest of the statement is ignored and then execution

continued after the block end, the rest of the script is then executed.

This is different to the next sub-section in which we study the 'do ... while' statement.

Okay folks, before we move on and go to the next section, lets look at a real example of 'while' being

used to do us a job - below in lines 10 through 15 we travel down the 'Stack' to access one element

after another until it is empty - study the following details :-

======================================================================================================

Yes, the above image is interesting, a nice example of how to reverse a string, variable or literal.

The big thing to remember here with 'while' is that the condition is checked before the full body of

the statement block is executed.

So if the condition is FALSE then the statement body is ignored.

Lets move on .......................

See you in the next sub-section.

PHH - 5th. November 2015.

Addendum : "Endless loops ? - always 'True' "

Well guys you may think this is slightly crazy - BUT - it has its uses.

Check out the following image details - thoroughly and carefully :-

We have used 'while' with a forced 'true' condition, to execute an endless loop, as it were.

The conditional statements can then be paced in the body of the loop statements - AND - can be

both numerous and quite complex.

Just be VERY careful NOT to be to clever - so you end up with script that is difficult to check out

for correct and proper logical execution.

Keep this simple stupid - KISS


do ... while/until statements

Okay then folks, these are not statements which I have always had available to me in some languages

I have coded in in the past.

These are also not statements which I feel I have had a hard time without - have I missed them ?

However, they do have their place and can sometimes be used in a tidier way that when we may use

an alternative loop statements in a slightly awkward way - and be can that be done !?

So lets see the 'do .. while' and 'do .. until' statements in action.

Once again we start off by using the very simple examples from Lee Holmes - its a start!

In the following examples do please remember that string comparison is NOT case sensitive.

See this image to prove my point :-

Lets move on a step or two ...........

The 'do .... while' statement :

If we are aware of case non-sensitivity, then lets move on - check out this simple image of a suitable example :-

I will leave you to do some more testing with the given script.

Basically we execute the block of commands (script lines) as long as a specified / chosen

condition applies. As long as the condition is TURE the commands are executed.

Moving on ..............

The 'do .... until' statement :

Before we discuss the condition and how comparison is made etc., let study a simple working

example, similar to that we saw above - check out carefully :-

So in the above example the block of commands (script lines) are executed as long as a

specified condition is NOT the case, or as long as the condition is FALSE.

Note that for both 'do' loops the full body of the statement block is executed - that is the main thing

to realise when making comparisons with other types of loops.

Take CARE when using these loops as it can be quite easy to get your logic and conditional statement

'not quite right', in which case it hard to fault find.

*** Note *** The 'Repeat ... Until' statement exists in other languages, as a slight variance of 'do ... until'.

See you in the next sub-section ................

PHH - 5th. November 2015.


Flow control - break / continue

PHH - 6th. November 2015.


Namespaces - also Generic / Collections

At first when we see PowerShell command line input and operation, we can' at all imagine that we

would ever get deep into .NET framework stuff, and list, collections and Generic related stuff.

Well, we were wrong to underestimate the power and scope of PowerShell.

We are certainly a long way from DOS and the command window, which seems to have been

its forefather.

Since PS5 is all about 'objects', then we must have Classes for these objects. And if we have

classes of objects then we must have Namespaces too.

Namespaces are a bunch of related Classes - "nothing more nothing less".

Intellisense - Helping us with 'Namespace's :

It would appear that we have a lot to learn about Namespaces and their WMI aspect - that is managing

or searching them in a read-only fashion.

However, at a user level, when wishing to make some quick and good progress, life is a bit easier.

Intellisense comes to our aid, but we done need to know something of what we are doing ;-0)

Study the following image details :-

=================================================================

Once we have typed 'system' and the following 'point' i.e. " . " we get intellisense providing a drop-list

of the possible options.

This drop-list is complete and if you can't find what you think you are after then you are making a mistake!

The more characters we type the shorter the drop-list becomes - see below :-

=============================================================================

If we choose another (alternative) option rather than 'Array' we can get a much longer possible

path or tree structure for the Namespaces.

Lets now try this as seen below :-

===============================================================================

And after selection we then see the following details :-

=========================================================================

And if we keep on going we see this :-

=========================================================================================

Which gives us some working script (almost) - try this for yourself :-

The same thing can be done to instantiate on object of class type Stack, Queue, OC (ObservableCollection)

and many others.

Time to move on, lets go and look at Stacks, Queues, List etc., etc..

See you in the next section.

PHH - 5th. November 2015.


Stack

Please be aware that there are two forms of 'Stack' we can use, it is a matter of whether we wish the

elements of the Stack to be similar and therefore typed, or just general and able to take mixed element

Types. We will demonstrate the use of both

===========================================================================

By chance I came across the need to use the Stack class from .NET and this

then opened the door for me to find out a simple enough way to use Namespaces other than

the one which seems to be the default for PowerShell and the ISE tool as it comes out of the box.

Here is what I saw when I searched in "Help Viewer 2.1" :-

=================================================================

After selecting the option shown in focus above, I saw the following in the RHS information pane

of the viewer :-

====================================================================================

This tells me the Namespace is "System.Collections" and so we can use it as seen in the

following image script - check this out :-

Study lines 2 and 4 in particular, and see how the casting can be done.

So lets build this into an alternative function to reverse a string input. We have done three earlier and

different versions so this is function four (4).

Study the details carefully :-

I can see at a glance from the blue results pane that this approach using a Stack is a lot slower.

Previously the time taken had been between 10 and 20 milliseconds.

Oh! - looking at the seconds above we have an output issue - no way is it taking 30 seconds.

It would appear that the seconds value is being wrongly formatted for what we are after.

PHH - 9th. November 2015.


Generic - typed form ...

PHH - 16th. November 2015.


Queue

PHH - 9th. November 2015.


List

Please be aware that there are two forms of 'List' we can use, it is a matter of whether we wish the

elements of the List to be similar and therefore typed, or just general and able to take mixed element

Types. We will demonstrate the use of both in this sub-section.

================================================================================

If we look to 'Help Viewer 2.1' for advice and information, then a search brings this up - see below :-

========================================================================================================================================

And also the following :-

=================================================================================================

So at least we now know which Namespace we need to use for 'List<T>'.

This means we can now script the following - check thoroughly :-

So above the image shows a strongly typed List of element type 'String'.

We can of course have any suitable object, including our own Classes - like 'Car' in the Chapter 9

section of these eNotes.

Lets now see a strongly typed List of Int32 elements :-

And to prove to you that the above List will not take elements other than Ints, we can try a string

assignment to see what happens - see the result below :-

Okay folks, it does not prove everything, but it does prove something ;-0)

Oh! and on that note, lets make the List work for us with mixed Types, all we need do is change

our declared type to 'Object' - see the following results :-

Yes, as we thought - it just works, and works well.

Time to move on ............................

PHH - 9th. November 2015.


ObservableCollection

Once again lets turn to Help Viewer 2.1 and search for 'ObservableCollection' :-

==================================================================================================================================

And so using the newer syntax in place of the 'New-Object' cmdlet we have the following success :-

PHH - 9th. November 2015.


Using our own Functions

PHH - 4th. November 2015.


Begin, Process, End - pipelining

PHH - 4th. November 2015.


Start Menu - Windows 10

http://www.computerperformance.co.uk/powershell/powershell_function_shortcut.htm

======================================================================================================

===========================================================================================================

PHH - 27th. December 2015.


Chapter 9 - STATIC properties & methods

As well all well know, the .NET framework is teeming with examples of STATIC properties

and methods, to aid our coding and now scripting.

In this chapter we will look at a set of commonly used such STATIC members.

https://technet.microsoft.com/en-us/library/dd347632.aspx

http://powershell.com/cs/blogs/tips/archive/2015/02/09/useful-static-net-methods.aspx

================================================================================================================================

For .NET we can do this :-

PHH - 30th. October 2015.


'Math' - System class

Let us do some interesting exploration, as well as a few experiments as well.

We will investigate the 'Math' namespace to see what it has to offer us - yes, the .NET one

that we may well already know and love ;-0)

Here is some detail from the Help Viewer 2.1 :-

=======================================================================================================================

Notice just above in the image and the Fields section, we have a STATIC field, or sometimes referred to as 'property'.

Now lets see this stuff from within the intellisense of the 'ISE' :-

===========================================================================================

Now lets see how to access these fields and format them perhaps.

Check these details below :-

And from Pi the circular constant to 'e' the base of natural logarithms :-

PHH - 1st. Nov. 2015.


'DateTime' structure

PHH - 1st. Nov. 2015.


'TimeSpan' structure

PHH - 1st. Nov. 2015.


Chapter 10 - Modules, Snippets, Profiles ....

There are a few important "sub-topics" which don't really fit into any other one specific and large

enough topic area to be on their own, or in their own chapter.

So this chapter, number 10, is to cover a number of such important mini-topics.

PHH - 19th. November 2015.


Snippets - 'ISE' and 'PS+'

Let us be practical folks, we are most likely to use only one IDE for our PowerShell work.

Either we use the Windows ISE free tool, or we use another third party tool like "PowerShell-PLUS".

I can't see many guys just using the PS console pane - unless forced to, for some reason.

From my first reasonable look at both ISE and PSP I would say that the more complex PSP has more

to offer guys who use Visual Studio. PSP still has many nice features while stay relatively simple compared

to Visual Studio.

For these reason we will not spend much time trying to move backwards and forwards between ISE and PSP.

However, we can have some fun in exploring how we may copy over Snippets and a couple of other interesting

tasks etc..

Personally, I feel that I will move further over to PSP now that I have made some solid and simple beginnings.

Obviously, the eBooks out there tend to focus on the standard Windows PowerShell tools - ISE and console.

So ISE is good to use to get going with PS5.

===============================================================================

Ed Wilson says this :-

.... "Snippets are pieces of code, or code fragments.

They are designed to simplify routine coding tasks by permitting the insertion of boilerplate code directly into

the script.

Even experienced scripters love to use the Windows PowerShell ISE snippets because they are great time

savers.

It takes just a little bit of familiarity with the snippets themselves, along with a bit of experience with the Windows

PowerShell syntax.

When you have met these requirements, you will be able to use the Windows PowerShell ISE snippets and create

code faster than you previously believed was possible.

The great thing is that you can create your own snippets, and even share them with others via the TechNet wiki. " ....

===============================================================================

Jones & Hicks say this in their eBook :-

[ I thoroughly recommend you purchase a copy, not least to get the supporting material for download .. ]

==========================================================================================================

They also say this - a good idea even without snippets :-

==========================================================================================================

Ed Wilson also gives this tip / trick about Templates :-

================================================================================================================

*** NOTE ***

Snippets and their use belong to the world of the IDE - that is, the development or scripting 'shell' - the

software tools used to create and run scripts.

As such, they are not a 'part' of Windows PowerShell - but we will find using snippets very convenient ;-0)

So snippets are part of the 'process' and not the 'action' ! They can make our life as developers simpler

and easier. lets get used to using them.

** Important ** it would appear that the 'snippet system' is not the same in ISE as in PSP and vice versa.

However, there looks to be some way to convert and make available, those from ISE in the PSP software

tool. More on this later.

=========================================================================

Lets start with checking out the relevant parts of "PowerShell PLUS - version 5.0".

In a standard / default launch of "PS Plus" (PSP) we usually see the Snippets pane as seen below :-

========================================================

Note that we can swap around the visible pane for the three tabs shown below :-

[ .. System Explorer, Code Snippets, and Source Control .. ]

============================================================

Lets now expand and view the pane, and then open up a few nodes, before we see some leaf entries :-

===================================================

And opening a couple of these nodes seen above, we get the following to choose from :-

[ .. we can only use the leaf nodes - a double click makes a copy appear in the pane in focus .. ]

=============================================================

If we select one of those on offer above, we see the following :-

================================================================================================

Yes, as you can see, a very easy and handy way to get the syntax correct ;-0)

Note that a snippet when used, will run in the standard console as the script code and commands are

just normal PowerShell stuff - see how we can use this snippet code in the PS console below :-

Obviously, some snippets will be more use to some people than to others, AND, the uncommon

syntax of some which are rarely used, will be VERY helpful indeed.

For keyboard short-cut guys it is 'Ctrl + J ' that we need to use - and that is also the key combination

we are to see for Windows PS-ISE as well. At least some things stay the same ;-)

Lets move on to the Microsoft standard tool ...............

Windows PS - 'ISE' snippets :

I prefer to use mouse and context menus, so right clicking in the edit pane work area, or

even the console pane in ISE, gives au the following choices :-

If you prefer to use the menu bar, then the 'Edit' tab provides these option choices :-

=================================================================

Okay then, lets go a step or two further - check these images below :-

And looking further down the option list - to check the syntax for 'Switch' we see the next image detail :-

All we need do while using the snippets is to click for selection and the shown script/code is

entered at the current cursor position.

Lets try some - both in the Console pane of ISE and also the script editor too. Lets start

with the 'do .... until' scripting structure :-

And this is what we see after selection - the cursor was in the editor :-

And if we do the same with the cursor in the console pane we see this below :-

PHH - 22nd. November 2015.


Creating Snippets

=================================================================================================================

*** Note ***

Here below, is a start from Ed Wilson - we will go further once we get our foot in the door (a start) !

New-IseSnippet -Title SimpleSwitch -Description "A simple switch statement" -Author "ed wilson" -Text "Switch () `r{'param1' { }`r}" -CaretOffset 9

Here is the same content 'line' copied to the ISE shell :-

==============================================================================================================

=============================================================================================================

==============================================================================================

PowerShell PLUS 5.0 :

The handling of snippets within the PS Plus environment is different, as much as anything it is more

sophisticated as the software tool is more complex than ISE and in many ways more advanced.

We can deal with snippets much easier it would seem - but then we are more removed from what is really

happening at a command level. We can't have it both ways ;-0)

In many ways it is better to keep as close to the PowerShell level of O/S management, so we can tell what

is being done - like in the previous section above this, when we dealt with snippets in the simpler ISE environment.

However, for a knowledgeable user, and busy administrators, then what we are about to explore has great benefits

I feel ;-)

Lets look at the 'Code Snippets' pane which can be docked and placed many places in the 'shell'.

By default it is over on the left hand side (LHS)

PHH - 22nd. November 2015.


Using Snippets

Windows PowerShell ISE :

===========================================

PowerShell PLUS 5.0 :

The handling of snippets within the PS Plus environment is different, as much as anything it is more

sophisticated as the software tool is more complex than ISE and in many ways more advanced.

We can deal with snippets much easier it would seem - but then we are more removed from what is really

happening at a command level. We can't have it both ways ;-0)

In many ways it is better to keep as close to the PowerShell level of O/S management, so we can tell what

is being done - like in the previous section above this, when we dealt with snippets in the simpler ISE environment.

However, for a knowledgeable user, and busy administrators, then what we are about to explore has great benefits

I feel ;-)

Lets look at the 'Code Snippets' pane which can be docked and placed many places in the 'shell'.

By default it is over on the left hand side (LHS)

PHH - 22nd. & 23rd. November 2015.


Removing Snippets

Okay folks before we can remove (or delete) a snippet from our system we must first have successfully made

or created one. Then we need to be able to find it and display it as well - that is not a bad idea ;-0)

In the earlier child-section of this chapter we saw how Ed Wilson recommended that we carry our such a snippet creation.

He said :-

And this below is what we used :-

In the above image we see the name is "SimpleSwitch" and by changing this we get second and third snippet entries.

Here is how we can make more - notice how we can split the lines with back-tick and an extra tab character :-

Okay then lets move on to removing ...........................

================================================================================================

Before we commit ourselves to removing a snippet item we need to do a check first - 'WhatIf' is our friend for this :-

Now then guys, I need to try and clear up a few ideas at this point. Ed Wilson's entry in his eBook slightly confused me when

he showed some sample command text.

Rather than the two command lines shown above, I prefer to think that we are going to try and Match the name of 'SimpleSwitch'

as well as doing a 'WhatIf'. Surely the point of the 'WhatIf' is to checkout doing what we intend - and I thought we were

trying to remove the 'SimpleSwitch' entry.

So guys, we need to 'Match' as well as use the 'WhatIf' property on the 'Remove-Item' cmdlet.

Check out the following :-

And here it is being run from the script editor :-

So once we are happy enough that it will do as we require, we camn then delete or comment out the 'WhatIf'.

Here we go :-

And doing our own check with the suitable command let we see the following in the console pane :-

Yep - we now have removed our only snippet entry of 'SimpleSwitch', and so have an empty list.

Lets move on a step or two .....................

PowerShell PLUS 5.0 :

The handling of snippets within the PS Plus environment is different, as much as anything it is more

sophisticated as the software tool is more complex than ISE and in many ways more advanced.

We can deal with snippets much easier it would seem - but then we are more removed from what is really

happening at a command level. We can't have it both ways ;-0)

In many ways it is better to keep as close to the PowerShell level of O/S management, so we can tell what

is being done - like in the previous section above this, when we dealt with snippets in the simpler ISE environment.

However, for a knowledgeable user, and busy administrators, then what we are about to explore has great benefits

I feel ;-)

Lets look at the 'Code Snippets' pane which can be docked and placed many places in the 'shell'.

By default it is over on the left hand side (LHS)

====================================================

PHH - 22nd. & 23rd. November 2015.


Conervting ISE snippets to PSP

PHH - 23rd. November 2015.


Templates

Ed Wilson says :-

================================================================================================================

http://9to5it.com/powershell-script-template/

==================================================================================================================

PHH - 22nd. November 2015.


Modules

*** Note ***

The preferred way to ship a provider is via a Windows PowerShell module.

Ed Wilson also says ...

"A module is a package that can contain Windows PowerShell cmdlets, aliases, functions,

variables, type/format XML, help files, other scripts, and even providers. "

In Windows 10 we see that Windows PowerShell core cmdlets reside in two basic modules, which

are the Microsoft.PowerShell.Management and Microsoft.PowerShell.Utility modules.

PHH - 22nd. November 2015.


PS Gallery

PHH - 22nd. November 2015.


Advanced Functions

Ed Wilson has this to say in his eBook :

... "Advanced functions incorporate advanced Windows PowerShell features and can therefore behave like 'cmdlets'.

They do not have to be complicated.

In fact, advanced functions do not even have to be difficult to write or to use.

What makes a function 'advanced' is the capabilities it possesses that enable it to behave in a similar manner to a cmdlet.

Back during the beta of Windows PowerShell 2.0, the name for the advanced function was 'script cmdlet', and although the

name change is perhaps understandable, because script cmdlets really are just advanced functions, in reality, the name

was very descriptive.

This is because an 'advanced function' mimics the behaviour of a regular Windows PowerShell cmdlet.

In fact, the best advanced functions behave exactly like a Windows PowerShell cmdlet, and implement the same capabilities. "

PHH - 22nd. November 2015.


Profiles

Profiles and Policies (Execution) :

Ed Wilson gives us some tips in his very useful eBook :-

A Windows PowerShell profile is a PS5 script that runs each time Windows PowerShell starts.

Care - Windows PowerShell does not enable script support by default.

In a network situation, the PS script execution policy might be determined by your network administrator via Group Policy.

[ Yes - you may have your hands tied ! ]

In a workgroup, or at home, the execution policy is not determined via Group Policy.

=============================================================================

There are six (6) and we can have many !

For older guys a 'profile' is like the old fashioned 'Autoexec.bat' file.

The 'profile' currently being run depends on the current logged user, and the current host etc., as

well as the different flavour of the PowerShell tool being launched.

So as Ed Wilson puts it, the 'Profile' is somewhat of a 'moving target'.

Lets do a simple experiment - lets see what the system variable $profile tells us !?

As we type the $profile at the prompt we get an intellisense drop list as seen above :-

And when we complete the entry and run the command we get the full path and file-name as seen below :-

Notice that this is for the 'ISE' tool - see the Title-bar in the above image.

Now lets do the same for the Windows console applet :-

Notice that the result in the console window is different, there is an 'ISE' character string less, or missing.

Now lets try the same thing from the 'PowerShellPlus' environment :-

This would appear to be the same as for the standard Windows PS console applet. So for me as a user

on my desktop PC I have two different Profiles to hand - provided that they have actually been created.

By default the Profile 'file' is missing until created - more on this below / later.

First lets look at these system variables :-

And as these get incorporated into Profile paths we see the following table details :-

=================================================================================================================

It would appear that one and five (1 & 5) of these apply to me right now.

PHH - 22nd. November 2015.


Creating our own Profile

http://www.howtogeek.com/126469/how-to-create-a-powershell-profile/

=====================================================================================================

https://technet.microsoft.com/en-us/library/ff461033.aspx

==============================================================================================================================================

Starting our own 'Profile' exploration :

First we need to check out our Execution Policy :-

Apparently, if it is 'RemoteSigned' then we are good to go for the rest of these test and trials.

If it is not for you then do the following :-

The important pat of this VERY long dialog box is shown below :-

Complete the input by clicking what seems like the correct buttons etc..

Then retry the 'Get-' to see what is what. below I seem to have done a couple of things more than once :-

So now check out the system variable to view the Profile path-name for ISE :-

So lets do a test to see if the file (for Profile) exists :-

And run this short command :-

So no (false) it does not exist on disk in the specific folder required.

Now we want to make a blank or empty copy of the required Profile - check below for details :-

And running this we see the following :-

Note the length of ' 0 ' or zero !

We can now open this empty file in the 'ISE' editor - that is what the following means, check it out :-

And running the command ............ :-

Brings up a tab in the editor like shown beneath :-

Yes, correct tab and correct file-path - also empty of script details.

I think that the freshly opened file shows only one line number - that of ' 1 '.

*** Puzzle ***

For some reason while researching and testing I did the following :-

But now I can't seem to be able to reproduce the action, or even find anything in the Help

Whoops !!! - solved it, the 'Set-Profile was a function I made while struggling my way through the

instructions in Ed Wilson's book - I did not find them clear, and/or was tired at the end of the day.

Now I understand how to make and apply Profiles, so just put the above down to learning the hard way ;-)

Lets now test to see we have a file on disk in the right place with the correct name :-

Lets do an important little test for where we are about to go - lets try the help updating :-

And here it is in full swing - check below :-

Now folks, let us return to the empty file open in out tab for the Profile - here it is :-

And now we need to study a few lines of commands that then need to be placed (typed) in the

blank file - check details below :-

Note that the console prompt entry is what opened the tab and file.

In the above image see that line 4 is pointing at a Script file. We need to see what is in this file, so we

can then appreciate what is likely to happen when it is run.

Check out carefully the following details :-

PHH - 24th. & 25th. November 2015.


Chapter 11 - the 'WMI' Model, and more

'WMI' is an acronym standing for "Windows Management Instrumentation".

It would appear to me that WMI has been around a long time, and even possibly from the early

days of 'Monad' - as PowerShell was called way back then.

I remember going to a presentation at Microsoft at the Thames Valley site, before I even got into

using .NET and Vulcan. And way before I used C#.

I was impressed with 'Monad' then, so although WMI works along side PS's cmdlet system, it

came well before it - so there will be no surprise to you if there are a few differences that we need

to come to terms with - or even get to love ;-0)

Checkout what Wikipedia has to say - here is the open snippet :-

====================================================================================================================================

Always read information on 'PowerShell' from the internet by mentally querying its age - things move and

change very rapidly in ICT and many articles are 'dated' - meaning they may not be wrong, still are probably valid,

but just do NOT present the current state of things. We generally need the latest 'slant' on things.

==========================================================================================================================

'WMI' has been around since Windows NT 4 - which seems a lifetime ago in IT and programming ;-0)

Lets now move on ..............

=========================================================================

Lets continue with what Ed Wilson has to say in his excellent eBook :-

Understanding the WMI model :

[ .. remember this is not .NET stuff .. ]

"WMI is a hierarchical namespace, in which the layers build on one another.

Although it is true that WMI is a hierarchical namespace, the term by itself does not really convey the richness of WMI.

The WMI model has three sections—resources, infrastructure, and consumers."

Apparently we need to confront and use the three sections for :-

Resources, Consumers, and Infrastructure.

And guess what, the Infrastructure section itself is made up of three parts ;-0) Parts for Service, Repository, and Providers.

Providers is the most major part of the the section - providers allow us to relatively easily gather lots of various information

that we require for our tasks in hand.

Brief explanation :-

Resources are all things that can be accessed, and are often thought of as 'stuff' outside of the main / core

system - external things like disks, folders, files and the file system itself, as well as network components,

event logs and "Active Directory Domain Services" (AD DS).

Consumers are things like cmdlets which take data in tidy, managed 'chunks' and then process this data from the WMI.

Other examples of 'Consumers' are certain types of VB script, as well as specialised software packages, tools, and utilities,

all which execute WMI queries.

Like a lot of things script and code wise - it is better to see these features in action than to try too much to explain

them in words.

Let us move on ...................

=========================================================================

The facilities within 'WMI' provide us with a huge number of classes to use. Obviously, the

information provided by these facilities are of interest to us developer guys, and particularly

of interest to system administrators - on stand alone and server based machines.

MSDN from Microsoft says this :-

============================================================================================

[ .. should this above be 'management of data' ? .. ]

*** The above sounds a bit stuffy and formal - we will see a better explanation (or two) as we progress

in this chapter. ***

*** Note that they call it an infrastructure and not a framework !? ***

*** As a .NET guy I find it a bit easier to think of it like a 'Framework'. ***

Okay then folks, we have 'management' of 'operating systems' which are Windows 'based'. These

O/S are for machines which are stand alone, as well as servers, these have 'data' associated with them.

So in effect it is this data which is being retrieved, viewed, and managed. And sometimes 're-set' or

're-configured' !?

Obviously, the categories and sub-categories of all these classes within WMI are tree structured.

[ .. roots to leaves via nodes .. ]

Lee Holmes provides us with a short list of four categories - see below :-

Computer system hardware :-

{ Cooling device, input device, mass storage, motherboard,

controller and port, networking device, power, printing, telephony, video, and monitor }

Operating system :-

{ COM, desktop, drivers, filesystem, job objects, memory and page files, multimedia audio/visual,

networking, operating system events, operating system settings, processes, registry,

scheduler jobs, security, services, shares, Start menu, storage, users, Windows NT event log,

Windows product activation }

WMI Service Management :-

{ WMI configuration, WMI management }

General :-

{ Installed applications, performance counter, security descriptor }

Below is an image of the "top of the tree" for accessing all the reference material which Microsoft provide :-

This web page is reached from the following link :-

https://social.msdn.microsoft.com/search/en-US?query=WMI

And here are a few more sections from further down the web page :-

==================================================================================================================

To make things easier for you are are some of the most used section links :-

https://msdn.microsoft.com/en-us/library/windows/desktop/aa394582%28v=vs.85%29.aspx

https://msdn.microsoft.com/en-us/library/aa384642(v=vs.85).aspx

https://msdn.microsoft.com/en-us/library/aa393964(v=vs.85).aspx

https://msdn.microsoft.com/en-us/library/aa394572(v=vs.85).aspx

https://msdn.microsoft.com/en-us/library/aa394554(v=vs.85).aspx

Moving on ..................

Lets now see some of the Classes for both hardware and software. In fact we will list and examine

very few of those classes available to us - just checking out a small representative sample.

Classes available (hardware) :

Win32_BaseBoard (motherboard)

Win32_DiskDrive

Win32_CDROMDrive

Win32_Processor - On a multiprocessor computer, one instance of the Win32_Processor class exists for each processor.

Win32_DesktopMonitor

Win32_OnBoardDevice

Win32_Printer

Classes available (software) :

Win32_BIOS

Win32_BootConfiguration

Win32_OperatingSystem

Win32_ComputerSystem

Win32_Desktop

Win32_Environment

Win32_LogonSession

WIN32_NetworkClient

Win32_PrintJob

Win32_Process

Win32_Product

Win32_Share

To see a few more and their details (meaning) check out chapter 7 of Lee Holmes text (eBook) or

look into the MSDN web based references.

PHH - 19th. November & 20th. December 2015.


The 'WMI' Tester software tool

Wikipedia has this to say :-

[ .. seems a bit dated talking of Windows NT and not Windows 8 / 10 !? .. ]

Lets now move on ................

===========================================================================

In Chapter 13 of his book Ed Wilson introduces us to a most useful software tool for working in WMI.

Although this tool can obviously be used for many things related to WMI work in PS5, we need to have

a specific target, or reason, when we first try it out.

Lets for now just go along with his opening example / sample - but first read what he has to say by way of

an introduction :-

" ... Regarding the 'Win32_SecurityDescriptorHelper' class .........

..........................................................................................................

We can look up the class in the Windows Management Instrumentation Tester (WbemTest).

The 'WbemTest' tool always exists with WMI.

To find it, you can type "WbemTest" from within Windows PowerShell.

From "WbemTest", click Connect.

Click Connect once again to connect to the default namespace.

Next, click 'Open Class' and enter "Win32_SecurityDescriptorHelper", and then click OK. "

Launch 'Wbemtest' form the Start menu or the console pane - check below :-

==============================================================

=================================================================

PHH - 23rd. December 2015.


Calling WMI methods - on WMI classes

Ed Wilson has another way of looking at using WMI 'stuff'.

He has a chapter (13) in his very fine eBook called "Calling WMI methods on WMI classes".

He gets us to focus on the difference between Instance methods and Static methods - how

to call these, and how to use suitable (WMI) cmdlets.

The particular cmdlet required for a lot of WMI work is called 'Get-WmiObject'.

This has an alias of 'gwmi'.

Let us use our newly acquired skills (and knowledge) to see which other related commands are

available for our use. Checkout the details in the following image :-

The above image is useful for checking the 'Source'.

Notice that there are Applications related to work with WMI as well as PS comdlets.

And if we check the following list, it is easier to read AND we highlight the 'Get' command let :-

Before we shoot-off and explore and experiment, let us see what Ed Wilson has to say on the subject.

"There are actually several ways to call Windows Management Instrumentation (WMI) methods in Windows PowerShell.

One reason for this is that some WMI methods are instance methods, which means they only work on an instance of a class.

Other methods are static methods, which means they do not operate on an instance of the class."

Us .NET guys should be familiar with the ideas involved in the above statements.

Before we look at instance and static method calling in some detail, lets spend a couple of minutes to see

just how we can get WMI data back from the system, using WMI techniques.

In the next image, shown below, we will see how with a small amount of script / code we can launch

a process based on an new instance of Notepad, and then retrieve details of this new process, and then

display these details.

Checkout below how lines 4 and 5 do all of this for us :-

Code line 5 of the script retrieves an object with many properties - above we see a few of the first to be listed.

And now in the next image we see a few of the very last properties listed - check this out :-

And here below is a few more from the middle of the A-Z listing :-

Yes, a long list of properties.

Notice in the middle one called 'Handle' and the value of this Handle property shows as '4484' and belongs

directly to the instance of Notepad we have opened.

If I close Notepad (or even leave it open) and then run the two lines of script once more (again) we will see

a different Handle value.

This makes it hard for me to design, develop, and run code as well as do some screen capturing - the values

keep on changing ;-0) Like working with wet and slippery soap ;-0)

Here is the handle detail of the first instance I opened this morning :-

Before we get in to this example too deeply, and have some coding and scripting 'fun', we

need to move on into the next sub-section which is all about 'Instance Methods'.

Join me there - see you soon ........................

PHH - 21st. December 2015.


Instance methods

Using WMI cmdlets to execute instance methods :

Okay then guys, let us continue the simple example from the parent section.

Let us first see the script / code and notice how the two lines 5 and 6 use both Alias and

Cmdlet to retrieve the WMI object of interest to us.

Study the following details :-

[ .. yes, 'gwmi' is an alias of 'Get-WmiObject' .. ]

The WMI object being retrieved above is one of Class type 'Win32_Process'.

In the code we have a variable called '$my_A' which is of this class type - notice some of the listed properties.

Also notice that path and relative path properties are different - i.e. __RELPATH and __PATH.

*** CARE *** So far in the above text and images we have only seen displayed the underscore properties.

However, when we come to code and use them we MUST use a double underscore - YES - it is two characters

of underscore, one directly after the other.

Here is a sample to demonstrate / illustrate this to you :-

You also have to realise that the handle value has changed many times as I have re-run the script. This

makes it hard to meaningfully comment the code used ;-0( As you can see, handle value 13640 is now 1044,

and has probably been a couple of other values in between.

Up till now, while experimenting, I have been removing / closing the opened instance of notepad as seen below :-

However, there are other ways to close down the Notepad GUI - and one is by code.

The Instantiated object of a Win32_Process has an instance Method called 'Terminate'.

This can be used easily from code - see below (line 14) :-

The action of the Method is to close down ONLY that instance of Notepad to which the method is

directly related - no other instance which is in existence.

Here is an image to show how intellisense provides us with the very long list of members - that

is properties and methods for the 'Win32_Process' class :-

============================================================================

*** Note *** Sometimes, intellisense does not seem to kick into action at the first attempt, and

even sometimes it appears as if we need to run the script once first, before it does what we expect.

Here it is again :-

====================================================================================================

Its time to move on a step or two.

Opening and Handling Multiple Instances of Notepad :

Let us look at the results of my code creating (opening) three instances of Notepad.

With these instances left open, we can run the following script to see what we actually have on

our open desktop. Checkout the details carefully :-

Ho! - Ho! - Ho! .... (in the spirit of Christmas), we seem to have four and not three !?

See above the four handle numbers / values.

On inspection I found that one of my GUI instances was directly over the top of another, so four looked like three.

If we use the Task View icon in the task bar of Windows 10 we see otherwise - check below :-

=======================================================================================================================

Notice the top line of four similar screens.

Moving on a few paces (steps) ................

Making our life easier with code - or do we ? - CARE !!!! :

I need to tell you a short story (very soon) as I juts then locked up my powerful desktop PC system by

a short piece of ill-thought-out script / code.

Although I had no computer way to checking it, I think I set in motion a script to instantiate an infinite

number of Notepad WMI Process objects.

Once the script was started my whole desktop became unresponsive and no matter what tricks I tried,

or key combinations pressed, it was all to no avail. It came down to me pressing the 'Reset' button on

the front of my desktop PC ;-0((

So let us tread most carefully as we do this next section.

The section is to open by some looping code, a large handful of Notepad instances. And then when

opening these we first check-out that we are not to get into a large or infinite loop for opening up one

after another.

Here is what I coded after my disastrous first attempt :-

In the above image we have a loop which goes around until the counter is of value 7.

By commenting the 'start process' line we avoid some of the possible issues / problems - BUT -

be careful because even an endless loop just counting could cause some sort of system lock up.

Once the loop counts and display correctly, and also finishes / completes, you can un-comment

the process line, or add new stuff.

After running the full script I got the desktop to look like this :-

And the script to generate these (without any desktop rearrangement) looks like the following :-

*** Note *** I am just executing the highlighted code section of the script pane, and this echoes

the code in the results / console pane.

Okay then folks, now that we have a whole bunch of instances of Notepad - up and running - let

us now see if we can get WMI techniques to find them, and even go through one by one and close

or terminate them.

We can have some real good fun ;-0)

Here below we have code to open and find a bunch of instances of Notepad :-

Yep! - the right number of handles, and also notice that the values seem rather random.

From the script above we are just running lines 9 through 13 as my seven instances already exist.

So how do we use an Instance Method to close, or terminate one of these instances ?

Well, in the following experiment we will try and use the handle values to allow us to remove from

the system (and hence desktop screen) any Notepad instance with a handle value of over '13200'.

Check this out carefully :-

========================================================

And now on screen we can see this - if you are in my office looking at my development PC :-

Yep! - three previously displayed instances are gone.

I will leave it up to you to find out which handle values have 'gone', disappeared etc..

We can use some similar script code to find this still existing - checkout below :-

Well, they are all under 13200 it would appear ;-0)

So then guys, how do we make our screen as that shown below ?

You can try this as seen in the next image :-

======================================================

The full script for this in in the child section from here, entitled 'script'.

When you try and test it you may have to change the handle value from 13200 to something which

suits your PC and operating system.

See you in the next sub-section on Static Methods ...............

PHH - 21st. December 2015.


script

===============================================================

#get-command *wmi*

for($my_Counter = 0; $my_Counter -lt 7; $my_Counter ++)

{

  Start-Process notepad

  $my_Counter

}

$my_Proc2 = Get-WmiObject Win32_Process -Filter "name = 'notepad.exe'"

foreach($my_Item in $my_Proc2)

{

  $my_Item.Handle

}

foreach($my_Item in $my_Proc2)

{

  if ($my_Item.Handle -gt 13200)

   {

      $my_Item.Terminate()

   }

}

$my_Proc3 = Get-WmiObject Win32_Process -Filter "name = 'notepad.exe'"

foreach($my_Item in $my_Proc3)

{

  $my_Item.Handle

}

===============================================================

for($my_Counter = 0; $my_Counter -lt 7; $my_Counter ++)

{

  Start-Process notepad

  $my_Counter

}

$my_Proc2 = Get-WmiObject Win32_Process -Filter "name = 'notepad.exe'"

foreach($my_Item in $my_Proc2)

{

  $my_Item.Handle

}

foreach($my_Item in $my_Proc2)

{

  if ($my_Item.Handle -gt 13200)

   {

      $my_Item.Terminate()

   }

}

$my_Proc3 = Get-WmiObject Win32_Process -Filter "name = 'notepad.exe'"

foreach($my_Item in $my_Proc3)

{

  $my_Item.Handle

}

foreach($my_Item in $my_Proc3)

{

  $my_Item.Terminate()

}

===============================================================

PS C:\> for($my_Counter = 0; $my_Counter -lt 7; $my_Counter ++)

{

   Start-Process notepad

   $my_Counter

}

$my_Proc2 = Get-WmiObject Win32_Process -Filter "name = 'notepad.exe'"

foreach($my_Item in $my_Proc2)

{

   $my_Item.Handle

}

0

1

2

3

4

5

6

12144

2440

11060

3348

13888

2252

10292

PS C:\> foreach($my_Item in $my_Proc2)

{

   if ($my_Item.Handle -gt 13200)

   {

       $my_Item.Terminate()

   }

}

__GENUS          : 2

__CLASS          : __PARAMETERS

__SUPERCLASS     :

__DYNASTY        : __PARAMETERS

__RELPATH        :

__PROPERTY_COUNT : 1

__DERIVATION     : {}

__SERVER         :

__NAMESPACE      :

__PATH           :

ReturnValue      : 0

PSComputerName   :

__GENUS          : 2

__CLASS          : __PARAMETERS

__SUPERCLASS     :

__DYNASTY        : __PARAMETERS

__RELPATH        :

__PROPERTY_COUNT : 1

__DERIVATION     : {}

__SERVER         :

__NAMESPACE      :

__PATH           :

ReturnValue      : 0

PSComputerName   :

__GENUS          : 2

__CLASS          : __PARAMETERS

__SUPERCLASS     :

__DYNASTY        : __PARAMETERS

__RELPATH        :

__PROPERTY_COUNT : 1

__DERIVATION     : {}

__SERVER         :

__NAMESPACE      :

__PATH           :

ReturnValue      : 0

PSComputerName   :

__GENUS          : 2

__CLASS          : __PARAMETERS

__SUPERCLASS     :

__DYNASTY        : __PARAMETERS

__RELPATH        :

__PROPERTY_COUNT : 1

__DERIVATION     : {}

__SERVER         :

__NAMESPACE      :

__PATH           :

ReturnValue      : 0

PSComputerName   :

PS C:\> $my_Proc3 = Get-WmiObject Win32_Process -Filter "name = 'notepad.exe'"

foreach($my_Item in $my_Proc3)

{

   $my_Item.Handle

}

12144

11060

10292

PS C:\>

foreach($my_Item in $my_Proc3)

{

   $my_Item.Terminate()

}

__GENUS          : 2

__CLASS          : __PARAMETERS

__SUPERCLASS     :

__DYNASTY        : __PARAMETERS

__RELPATH        :

__PROPERTY_COUNT : 1

__DERIVATION     : {}

__SERVER         :

__NAMESPACE      :

__PATH           :

ReturnValue      : 0

PSComputerName   :

__GENUS          : 2

__CLASS          : __PARAMETERS

__SUPERCLASS     :

__DYNASTY        : __PARAMETERS

__RELPATH        :

__PROPERTY_COUNT : 1

__DERIVATION     : {}

__SERVER         :

__NAMESPACE      :

__PATH           :

ReturnValue      : 0

PSComputerName   :

__GENUS          : 2

__CLASS          : __PARAMETERS

__SUPERCLASS     :

__DYNASTY        : __PARAMETERS

__RELPATH        :

__PROPERTY_COUNT : 1

__DERIVATION     : {}

__SERVER         :

__NAMESPACE      :

__PATH           :

ReturnValue      : 0

PSComputerName   :

PS C:\>

===============================================================

PHH - 21st. December 2015.


Instance methods - Invoking

Lee Holmes in his 'CookBook' says this :-

"When WMI or CIM returns information about a specific operating system process, that is called an instance.

As with static methods on .NET types, many WMI and CIM classes offer methods that relate broadly to the

entity they try to represent.

For example, the 'Win32_Process' class defines methods to start processes, stop them, and more.

To invoke any of these methods, call the 'Invoke-CimMethod' cmdlet."

We need to now do some experimenting and exploring ..........

===========================================================================================================

Here is an alternative way to use the Method called 'Create' in the Win32-Process class :-

=====================================================================

PHH - 22nd. December 2015.


script

PHH - 22nd. December 2015.


Static methods

Using WMI cmdlets to work with static methods

Here is 'Rule One' - as in Gibb's rules from NCIS ;-0))

" 'Get-WmiObject' returns instances of the class provided to it - always ! "

"Static methods do not use an instance of the WMI classes - the 'Get-WmiObject' command does not work."

Rule Two :

"Generally, in Windows PowerShell, a double colon is required to call a Static Method - this is for .NET classes."

Rule Three :

"Here, in WMI, there appears to be no difference between calling a static method or calling an instance method."

Below we see a STATIC Method called 'SDDLToBinarySD' :-

======================================================================================================

One way to call this Method in script, or code, is shown in the following image :-

We have had to make an adjustment to the code being used in Ed Wilson's example, simply because

I do not have a suitable folder from the root of my C: device. See below :-

And here is the proof from the File Explorer :-

============================================================================

To prove what we are doing is a-okay, lets make a new appropriately named folder on the C:

SSD device I have here :-

And to prove it see the newly captured File Explorer pane :-

=============================================================================================

Yes, I know, I am a 'Sad Harry', working on Christmas Eve ;-0)

Trying another way to call a Static Method :

There is a special cmdlet which allows us to call a class method directly in WMI, even a Static method.

Check the calling code first, before we move on to find the command-let and its details :-

Yes, we need to use the 'Get-Command' cmdlet to find all items in the cmdlet set starting with 'Invoke' - check this out :-

Nearly at the very bottom of the list do we see 'Invoke_WmiMethod', which is what we are after, and need to use.

And there is some more useful information in help, under 'Description' and other ...........

Now then folks, this is probably enough for one small sub-section, however, it would appear that we need to

look into CIM cmdlets and how these are used.

'CIM' being the "Common Interface Model".

PHH - 21st. & 24th. December 2015.


script

PHH - 21st. December 2015.


example - Win32_BIOS

=====================================================

==============================================================================================================================================================

===========================================================================================

=========================================================================================================================================================================

==============================================================================

=========================================================================================================================================

===============================================================================================

===============================================================================================================

====================================================================================

=======================================================================================================

================================================================================================

PHH - 20th. December 2015.


script

# wmi-win32_bios.ps1

# Demonstrates use of Win32_Bios WMI class

# Thomas Lee - tfl@psp.co.uk

# Helper function to return characterics of the BIOS

function get-WmiBiosCharacteristics {

param ([uint16] $char)

# parse and return values

If ($char -le 39) {

switch ($char) {

0   {"00-Reserved"}

1   {"01-Reserved"}

2   {"02-Unknown"}

3   {"03-BIOS Characteristics Not Supported"}

4   {"04-ISA is supported"}

5   {"05-MCA is supported"}

6   {"06-EISA is supported"}

7   {"07-PCI is supported"}

8   {"08-PC Card (PCMCIA) is supported"}

9   {"09-Plug and Play is supported"}

10  {"10-APM is supported"}

11  {"11-BIOS is Upgradable (Flash)"}

12  {"12-BIOS shadowing is allowed"}

13  {"13-VL-VESA is supported"}

14  {"14-ESCD support is available"}

15  {"15-Boot from CD is supported"}

16  {"16-Selectable Boot is supported"}

17  {"17-BIOS ROM is socketed"}

18  {"18-Boot From PC Card (PCMCIA) is supported"}

19  {"19-EDD (Enhanced Disk Drive) Specification is supported"}

20  {"20-Int 13h - Japanese Floppy for NEC 9800 1.2mb (3.5, 1k Bytes/Sector, 360 RPM) is supported"}

21  {"21-Int 13h - Japanese Floppy for Toshiba 1.2mb (3.5, 360 RPM) is supported"}

22  {"22-Int 13h - 5.25 / 360 KB Floppy Services are supported"}

23  {"23-Int 13h - 5.25 /1.2MB Floppy Services are supported"}

24  {"24-Int 13h - 3.5 / 720 KB Floppy Services are supported"}

25  {"25-Int 13h - 3.5 / 2.88 MB Floppy Services are supported"}

26  {"26-Int 5h, Print Screen Service is supported"}

27  {"27-Int 9h, 8042 Keyboard services are supported"}

28  {"28-Int 14h, Serial Services are supported"}

29  {"29-Int 17h, printer services are supported"}

30  {"30-Int 10h, CGA/Mono Video Services are supported"}

31  {"31-NEC PC-98"}

32  {"32-ACPI supported"}

33  {"33-USB Legacy is supported"}

34  {"34-AGP is supported"}

35  {"35-I2O boot is supported"}

36  {"36-LS-120 boot is supported"}

37  {"37-ATAPI ZIP Drive boot is supported"}

38  {"38-1394 boot is supported"}

39  {"39-Smart Battery supported"}

}

Return

}

If ($char -ge 40 -and $char -le 45) {

        "{0}-Reserved for BIOS vendor" -f $char

return

}

If ($char -ge 48 -and $char -le 63) {

          "{0}-Reserved for system vendor" -f $char

return

}

"{0}-Unknown Value " -f $char

}

# Get BIOS information from WMI

$bios = Get-WMIObject Win32_Bios

# Display BIOS Details

"Win32_Bios WMI Information"

"Bios Characteristics"

foreach ($ch in $bios.BiosCharacteristics) {

"                      :  {0}" -f  (Get-WmiBiosCharacteristics($ch))

}

"Bios Version          :  {0}" -f $bios.BiosVersion

"Codeset               :  {0}" -f $bios.Codeset

"CurrentLanguage       :  {0}" -f $bios.CurrentLanguage

"Description           :  {0}" -f $bios.Description

"IdentificatonCode     :  {0}" -f $bios.IdentificatonCode

"InstallableLanguages  :  {0}" -f $bios.InstallableLanguages

"InstallDate           :  {0}" -f $bios.InstallDate

"LanguageEdition       :  {0}" -f $bios.LanguageEdition

"ListOfLanguages       :  {0}" -f $bios.ListOfLanguages

"Manufacturer          :  {0}" -f $bios.Manufacturer

"OtherTargetOS         :  {0}" -f $bios.OtherTargetOS

"PrimaryBIOS           :  {0}" -f $bios.PrimaryBIOS

"ReleaseDate           :  {0}" -f $bios.ReleaseDate

"SerialNumber          :  {0}" -f $bios.SerialNumber

"SMBIOSBIOSVersion     :  {0}" -f $bios.SMBIOSBIOSVersion

"SMBIOSMajorVersion    :  {0}" -f $bios.SMBIOSMajorVersion

"SMBIOSMinorVersion    :  {0}" -f $bios.SMBIOSMinorVersion

"SoftwareElementID     :  {0}" -f $bios.SoftwareElementID

"SoftwareElementState  :  {0}" -f $bios.SoftwareElementState

"TargetOperatingSystem :  {0}" -f $bios.TargetOperatingSystem

"Version               :  {0}" -f $bios.Version

PHH - 20th. December 2015.


example - Win32_BaseBoard

PHH - 20th. December 2015.


example - Win32_Processor

===============================================================================================================

==========================================

===================================================================================

===============================================================================================

PHH - 20th. December 2015.


script

===========================================================

$objProc = Get-WmiObject Win32_Processor

If ($objProc.Architecture -eq 0 )

{

  "x86"

}

ElseIf ($objProc.Architecture -eq 9 )

{

  "Slot 2"

}

Else

{

  "Unknown"

}

"`-----------------------------"

$objProc.Architecture

===========================================================

<#strComputer = "."

Set objWMIService = GetObject("winmgmts:" _

& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set colOSes = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")

For Each objOS in colOSes

 Wscript.Echo "Computer Name: " & objOS.CSName

 Wscript.Echo "Operating System"

 Wscript.Echo "  Caption: " & objOS.Caption 'Name

 Wscript.Echo "  Version: " & objOS.Version 'Version & build

 Wscript.Echo "  BuildNumber: " & objOS.BuildNumber 'Build

 Wscript.Echo "  BuildType: " & objOS.BuildType

 Wscript.Echo "  OSProductSuite: " & objOS.OSProductsuite 'OS Product suite

 Wscript.Echo "  OSArchitecture: " & objOS.OSArchitecture

 Wscript.Echo "  OSType: " & objOS.OSType

 Wscript.Echo "  OtherTypeDescription: " & objOS.OtherTypeDescription

 WScript.Echo "  ServicePackMajorVersion: " & objOS.ServicePackMajorVersion & "." & _

  objOS.ServicePackMinorVersion

Next

Wscript.Echo "Processors"

Set colCompSys = objWMIService.ExecQuery("Select * from Win32_ComputerSystem")

For Each objCS in colCompSys

 WScript.Echo "  NumberOfProcessors: " & objCS.NumberOfProcessors

 WScript.Echo "  NumberOfLogicalProcessors: " & objCS.NumberOfLogicalProcessors

 WScript.Echo "  PCSystemType: " & objCS.PCSystemType

Next

Set colProcessors = objWMIService.ExecQuery("Select * from Win32_Processor")

For Each objProcessor in colProcessors

 WScript.Echo "  Manufacturer: " & objProcessor.Manufacturer

 WScript.Echo "  Name: " & objProcessor.Name

 WScript.Echo "  Description: " & objProcessor.Description

 WScript.Echo "  ProcessorID: " & objProcessor.ProcessorID

 WScript.Echo "  Architecture: " & objProcessor.Architecture

 WScript.Echo "  AddressWidth: " & objProcessor.AddressWidth

 WScript.Echo "  NumberOfCores: " & objProcessor.NumberOfCores

 WScript.Echo "  DataWidth: " & objProcessor.DataWidth

 WScript.Echo "  Family: " & objProcessor.Family

 WScript.Echo "  MaximumClockSpeed: " & objProcessor.MaxClockSpeed

Next

#>

#$objServ = Get-WmiObject Win32_Processor

#$objServ = Get-WmiServiceObject Win32_Processor

#get-help Get-WmiObject -examples

#$objServ = Get-WmiObject Win32_Processor -Class Win32_Service

#$objWmiServ = Get-WmiObject Win32_Service

#$colProcessors = $objWmiServ.ExecQuery("Select * from Win32_Processor")

#Get-Command Get-WmiServiceObject Win32_Processor

#Get-Command Get-WmiObject

#Get-WmiObject -Class Win32_Service

#$objServ = Get-WmiObject -Class Win32_Service | gm

#$objServ = Get-WmiObject -Class Win32_Processor | gm

#$colProcessors = $objServ.   .ExecQuery("Select * from Win32_Processor")

#$objServ = Get-WmiObject -Class Win32_Processor

#$objServ

$objColProcs = Get-WmiObject -Query "Select * from Win32_Processor"

$objColProcs

Write-Host "  ComouterName: " $objColProcs.PSComputerName

Write-Host "  Manufacturer: " $objColProcs.Manufacturer.ToString()

Write-Host "  Name: " $objColProcs.Name

Write-Host "  Description: " $objColProcs.Description

Write-Host "  ProcessorID: " $objColProcs.ProcessorId

Write-Host "  Architecture: " $objColProcs.Architecture

Write-Host "  AddressWidth: " $objColProcs.AddressWidth

Write-Host "  NumberOfCores: " $objColProcs.NumberOfCores

Write-Host "  DataWidth: " $objColProcs.DataWidth

Write-Host "  Family: " $objColProcs.Family

Write-Host "  MaximumClockSpeed: " $objColProcs.MaxClockSpeed

===========================================================

PHH - 20th. December 2015.


examples - Operating System Classes

===================================================================================================================

========================================================================================================================================================

======================================================================================

============================================================================================================================================

=============================================

===============================================

PHH - 20th. December 2015.


example - Win32_Desktop

==========================================================================================================

======================================================================================================================================

===========================================================================================

====================================================================================

PHH - 20th. December 2015.


script

$desktops = Get-WmiObject win32_desktop

"This system has {0} desktop objects" -f $desktops.length

Foreach ($dt in $desktops) {

"Desktop {0}" -f $i++

"  BorderWidth           : {0}" -f $dt.BorderWidth

"  Caption               : {0}" -f $dt.Caption

"  CoolSwitch            : {0}" -f $dt.CoolSwitch

"  CursorBlinkRate       : {0}" -f $dt.CursorBlinkRate

"  Description           : {0}" -f $dt.Description

"  DragFullWindows       : {0}" -f $dt.DragFullWindows

"  GridGranularity       : {0}" -f $dt.GridGranularity

"  IconSpacing           : {0}" -f $dt.IconSpacing

"  IconTitleFaceName     : {0}" -f $dt.IconTitleFaceName

"  IconTitleSize         : {0}" -f $dt.IconTitleSize

"  IconTitleWrap         : {0}" -f $dt.conTitleWrap

"  Name                  : {0}" -f $dt.Name

"  Pattern               : {0}" -f $dt.Pattern

"  ScreenSaverActive     : {0}" -f $dt.ScreenSaverActive

"  ScreenSaverExecutable : {0}" -f $dt.ScreenSaverExecutable

"  ScreenSaverSecure     : {0}" -f $dt.creenSaverSecure

"  ScreenSaverTimeout    : {0}" -f $dt.ScreenSaverTimeout

"  SettingID             : {0}" -f $dt.SettingID

"  Wallpaper             : {0}" -f $dt.Wallpaper

"  WallpaperStretched    : {0}" -f $dt.WallpaperStretched

"  WallpaperTiled        : {0}" -f $dt.WallpaperTiled

""

}

PHH - 20th. December 2015.


example - Win32_Product

=================================================

http://powershell.com/cs/media/p/18510.aspx

==================================================================

=====================================================================================================================================================================================

PHH - 20th. December 2015.


script

=================================================================

$name = (Get-Item env:\Computername).Value

$filepath = (Get-ChildItem env:\userprofile).value

$name

$filepath

Get-WmiObject win32_Product -ComputerName $name |

Select Name,Version,PackageName,Installdate,Vendor |

Sort Installdate -Descending |

Out-GridView

=================================================================

$name = (Get-Item env:\Computername).Value

$filepath = (Get-ChildItem env:\userprofile).value

$name

$filepath

$a = "<style>"

$a = $a + "BODY{background-color:Lavender ;}"

$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"

$a = $a + "TH{border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color:thistle}"

$a = $a + "TD{border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color:PaleGoldenrod}"

$a = $a + "</style>"

Get-WmiObject win32_Product -ComputerName $name |

Select Name,Version,PackageName,Installdate,Vendor |

Sort Installdate -Descending |

ConvertTo-html -Head $a -Body "<H2> Software Installed</H2>" >> "$filepath\$name.html"

=================================================================

$name = (Get-Item env:\Computername).Value

$filepath = (Get-ChildItem env:\userprofile).value

$name

$filepath

$my_Results = (Get-WmiObject win32_Product -ComputerName $name |

Select Name,Version,PackageName,Installdate,Vendor |

Sort Installdate -Descending)

$my_Results |Out-GridView

"Total number :- " + $my_Results.length.ToString()

=================================================================

PHH - 20th. December 2015.


example - Wireless networking

=======================================================================================

PHH - 24th. December 2015.


script and C# code

===========================================================

ManagementClass mc = new ManagementClass("root\\WMI",

"MSNdis_80211_ServiceSetIdentifier", null);

ManagementObjectCollection moc = mc. GetInstances();

foreach (ManagementObject mo in moc)

{

string wlanCard = (string)mo["InstanceName"];

bool active;

if (!bool.TryParse((string)mo["Active"], out active))

{

active = false;

}

byte[] ssid = (byte[])mo["Ndis80211SsId"];

}

===========================================================

PHH - 24th. December 2015.


Chapter 12 - CIM (Common Information Model)

"Common Information Model" - Wikipedia has this to say :-

==============================================================================================================================================================

And new version are frequently published - check below :-

================================================================================================

PHH - 24th. December 2015.


Finding the CIM classes

The good thing about learning, exploring, and using PowerShell is that we can use what we learn to

find out new things - fresh 'stuff'.

Lets see what we can do with cmdlets we know to find out more about CIM classes etc. :-

Yes, we have a large bunch to look at - 1554 in total.

Lets break these down into smaller bunches, not quite handfuls ;-0)

Study the image seen below :-

The figures above show totals that we may have more or less guessed at as general values - meaning

lots of Win32 and many CIM ones as well.

PHH - 24th. December 2015.


Using the CIM cmdlets - exploring WMI classes

Ed Wilson has this to say in his eBook :-

====================================================================================================================================

So it seems pretty obvious that CIM as it is now (today) came well after WMI existed, and was being widely used.

This means we need to have a working knowledge of both WMI and CIM.

And also note that we are using 'cmdlets' with both of the above - we need to know and use the lot ;-0)

There are a lot ! Check the next image :-

Yes, 1554 it would seem !!

A bunch starting with "Win32_" - see below :-

Another bunch starting with "CIM_" and a few are as seen below :-

A bunch more with 'MSFT' or 'Msft', and a few odds and sods as shown below :-

And finally, there are a few double underscore items in the class array as well - see below :-

And now we can follow along with the example in Ed Wilson's eBook, in Chapter 14.

Lets do a double ' * ' (start / asterisk ) search for 'computer' :-

And if we find the length of the array of items we see this :-

Yes, we have thirteen.

PHH - 24th. December 2015.


Finding the WMI class Methods

Once we find a single class we can then find its Methods. Remember Methods are related

to 'actions' of a class. Properties just describe things in classes.

Lets get our single class as shown below :-

And once we have the single object for a class we can them find and display the Methods, as seen below :-

And here is the fuller and wider list :-

PHH - 24th. December 2015.


Chapter 13 - SQL access and manipulation

*** NOTE *** Work with 'SQL Server' in PowerShell is done using the "SQL Server PowerShell Provider".

For more details on this see part of Appendix 'P' which is all about Providers.

The following shows how to simply and easily move between Providers that we are most likely to use :-

==============================================================================

Okay guys, in this chapter we are going to use some of the knowledge and skills we have so far

learned and picked up while studying PowerShell 5.

In his cookbook, Lee Holmes tells us that it is the cmdlet 'Invoke-SqlCommand' that we will need to use.

Here is what is written in his book :-

[ .. don't get mixed up between the 'Invoke-Sql' cmdlet and his own script file called 'Invoke-SqlCommand.ps1' .. ]

[ .. yes, its a bit confusing .. ]

================================================================================

In fact this may NOT be entirely correct, we need to explore a little !!

Let us start where we usually do, by seeing just which command-lets and aliases exist for us to use.

Here is what I did with my PS5 system in my latest Windows 10 O/S (build 11082) :-

Yes, studying the above output it would seem that there is only one 'cmdlet' we can use, and

that is "Invoke-Sqlcmd".

Lets try that on its own :-

And it would also appear that the details from the command-let are in 'SQLPS' - I would guess this means SQL Power

Shell.

This may be what is called a 'snap-in' !?

We don't really need to know any more than the correct name in order for us to get positive results.

Now that we know which cmdlet we will use to do all of our SQL work and exploration, lets move on

to the first child section from here, where we will use Help to find out more information.

See you there .................

PHH - 30th. December 2015.

Addendum :

No, it would appear that it is NOT a 'snap-in' but a Provider.

Here is how to check for snap-ins :-

The following image gives us a clue as to what we are using when we do SQL work in PowerShell :-

[ .. https://msdn.microsoft.com/en-us/library/cc281947(v=sql.120).aspx ..]

===============================================

Yes, we are using an appropriate 'Provider'.

Notice in the following image the information before the chevron or greater than sign :-

However, the cmdlets found relating to "sql" text searching pattern are the same set whether we use the disk

provider or the server provider - the full set is shown below :-

Yep! - out of all this lot we have only one 'Invoke' command-let.


Getting tips and ideas from 'Help'

Here is a first start to using HELP :-

PHH - 30th. December 2015.


Basic access

*** NOTE *** Once we gain access to a SQL Server instance, and can also gain access to an existing SQL

database, we can do just about anything we like or require, as far as 'things SQL' are concerned.

Any limitations you are likely to come across will be to do with your inabilities with T-SQL code and not PS5.

==============================================================================

Well folks, before we even try to do anything a bit clever, or fancy, we MUST checkout that we are

actually gaining correct access to our SQL Server instance.

Once we are accessing a Server, we can worry about databases, and then Tables, etc., etc..

I always find it most helpful to start with Management Studio (MS) when try to get the correct Server.

Here is what my 'Task Bar' shows :-

I have opened the Management Studio after first using the 'Connect to Server' dialog screen - see below :-

If you have not used this for a while try using the 'Browse for more .. ' option first, so that all possibilities

are included in the list provided.

When you have a short list of available Servers, choose one most likely to work (local knowledge), and

one which will have attached databases, with Tables.

Here, for my desktop set-up, I am using 'BIG-T' in preference to 'BIG-T\SQLEXPRESS' :-

=================================================

[ .. note the available DB (database) is 'WillieM2' .. ]

Okay then, since we know that "BIG-T" will work let us try using it in our script from PowerShell.

Below I am using a simple example from the HELP information :-

And to prove what I am doing all makes sense I can do the same from the other Server - note

below that there is a few hours difference between when I used the scripts ;-0)

Okay then guys, if we are getting success with such a simple test then we can think of going that

much further.

See the next sub-section for some new and interesting 'stuff'.

See you there ..................

PHH - 30th. December 2015.


Retrieving data from Tables - 'SELECT'

Okay folks, we are getting somewhere with this SQL oriented chapter ;-0)

We are now about to see how easy it is to find and retrieve data from a Table in a SQL database.

If we can get back queried data in a results set then we can do just about everything we require as

far as managing a SQL database is concerned.

As per usual, lets start with what we can do with Management Studio - how do we get back some

sample data using the GUI driven tools ?

Lets use the GUI environment to ask for a results set check below :-

=========================================================

And here below is what was generated for me when I chose the above context menu option :-

================================================================================

Yes, that is fine, so if we copy the auto-generated text we can use it within our script.

Here is what I have copied and generated - study in detail :-

Yes, we made the full auto-generated query text into a sting variable, named $my_query2".

Note above that the console output appears to be for us if we do not pipe, or pass on, the result data to

another cmdlet etc..

We can take care of the data output ourselves, and make a nice grid as seen below :-

Oh! and in preparation for us making longer and longer query / Select statements, lets see how we can

make and manage a composite query statement - check lines 12 and 13 :-

Oh! - and the benefit (or one of them) is that we can now sort the result items before display.

Checkout the following image details - line 16 in particular :-

Okay guys, we are making good progress I feel, but we have done enough for one small sub-section.

Lets move on, see you in the next one ....................

PHH - 30th. December 2015.


Making changes in the Database - 'INSERT'

I always tend to think that once we get the ability to change data within a database / table, then

we are starting to get some real 'power' !

Reading back stored data is one thing creating new data nad changing old data is quite another ;-0)

=======================================================================

Once again let us start with the Management Studio details in the 'Object Explorer' :-

We need to find and identify the database, the schema and the table itself :-

===================================================

Then we can use the above details to create a suitable PowerShell script - see lines 2 through 5 below :-

Notice in the above image the newly added rows - these have an 'AttendeeID' of over 1000, which must be

the seed that I set way back when I created the database.

Please be aware that T-SQL script created in the GUI environment of Management Studio has 'GO' text lines

embedded within it - these belong to the MS environment and NOT the T-SQL code. They delineate one

select query to the next.

Check this following image to see what I mean - there are two queries below :-

===============================================================

Now look back at the PS script code lines 2 - 5 and see how I have stripped out the 'GO's so as

not to generate errors.

Lets now use the GUI to see what we have in the Attendee table :-

==============================================================================

Okay, you can see a 'Richard Hanson', he was added prior to Cliff and Elizabeth, when I was doing a

test / trial.

Now then, lets change the code in line 2 way above, and change it into that in the following image, at

lines 1 and 2 :-

And if we now use the GUI in MS we can see the results of all my testing ;-0)

===================================================

Rows with values 1000 - 1009 must have been removed by deletion, I remember doing a few

deletion sessions.

Note that the auto-provision of the Identity always keeps 'going up', or increasing, it never fills

in any gaps for missing values after they have been deleted / removed.

See you in the next sub-section ..............

PHH - 30th. December 2015.


Running a T-SQL script file

Okay then folks, what we are after in this short sub-section is finding a useful and easy way to have

our T-SQL script /code in an external file, and then being able to use the file-path in the call

to the invoking cmdlet.

Once we can send queries to the DB from a script file, then we can create and use large scripts, which can

effectively do anything we require as far as SQL Server work is concerned.

Lets us start the 'wrong' way round, with the final working PowerShell script - check below :-

[ .. note lines 2 and 5 have variables which are text strings representing file-paths .. ]

The script in the above image adds a couple of extra rows to the 'Attendee' Table.

The actual T_SQL script is held in two text files made manually by me in Notepad.

Here below is the first such text file - the script is to add rows by insertion :-

================================================================================================================

In the next image seen below we have a second text file - check it out :-

=====================================================================================================

And if we open this file we see the detail shown in the following image :-

==================================================================================================

Yes, this script is simply that to query and return a dataset from the Attendee table.

For our purposes 'TOP 50' could well have been ' * ', meaning ALL / Everything.

*** NOTE *** a secondary filename of '.sql' is possibly better than '.txt', as this is what you may see

in the literature.

Lets move on, see you in the next sub-section ........................

PHH - 30th. December 2015.


'UPDATE' operations

Okay you guys, CRUD is always an issue with any coding system which allows us to access SQL

Server databases.

We all tend to think that if we can do all the basic CRUD operations then we are somewhat in control ;-0)

Lets continue with our SQL in PowerShell by doing some UPDATE processing on a simple test database

made solely for the purpose of testing and trialling.

Checkout below the "Stock" DB - at the moment it only has two tables - 'Product' and 'NewPrices'. It was

to have been 'NewPrice' but old habits die hard !!

Checkout the following details - of the two Tables :-

=================================================

Okay then folks, so we have two tables - lets now see the data that I manually entered, while

in 'edit' mode in the Management Studio (MS) environment - first the Product table details :-

=================================================================================

And now the few rows of update price details :-

===============================================================================

Note the 'UpDate' is supposed to be the date on which the new price of the product was issued,

hence the variation in date.

Now then, for the more 'crunchy' stuff ;-0)

Checkout below the code required to apply the new price data to the Product table :-

==============================================================

Remember that we must not have any 'GO' statements as these belong to MS and its 'shell' environment.

Here is what I got when I ran the code in MS :-

==============================

Yes, as expected we have changes on three rows.

So how do we put this code into a runnable script ?

Well, study carefully the following image details - lines 2 through 6 in particular :-

Please be aware that the single space added at the end of the lines in 2 - 6 are important for the

syntax to be correct. They act as separators for the clauses, and without any of those on lines 2 - 5 we

will get error messages. Try this for yourself if you are new to SQL, or have limited SQL experience.

Notice the 'GridView' object in the above image, the three changed dates can easily be seen on rows

2, 3 and 7.

Lets now look at the same changed data from within the MS shell - checkout below :-

================================================================================

Yes, I know the Table design is not great, and that a Product ID is missing as such. But,

it was simplicity that I was after, and I did not want any key constraints either. I will be

using this test DB in other places where we need such simplicity to make our PS work easier.

Lets now move on, see you in the next sub-section ..................

PHH - 31st. December 2015.


Chapter 14 - Microsoft and the 'Future'

PHH - 28th. November 2015.


Chapter 15 - the Windows 'Registry'

Good Advice - SAFETY !!!

Before doing any real work with the Registry (more than trivial stuff) go and make yourself a VM

(virtual machine) and then launch and use that to create and destroy Registry Keys and the likes.

See the appropriate Appendix section on making a VM.

Here is what Lee Holmes has to say :-

=====================================================================================

Although most guys are WARNed-off the Registry, and told not to 'go there', not to touch it nor

mess with it, there are times when it is a MUST to do some maintenance and management.

A carefully selected Registry Cleaner sorted out my issues when upgrading a long existing Windows

platform to Windows 10. Things now work well it would seem - so I had a need of maintenance.

*** CARE *** just be very careful as to what you do while learning and experimenting with PS5 and

the related stuff.

Remember to use a Virtual Machine to be on the safe side ;-0) Then it does not matter if you do any

real damage.

Lets get cracking and move to the first sub-section and start to learn.

See you there .....................

PHH - 1st. January 2016.


What and Why !?

Lee Holmes explains in his CookBook that the Registry is a configuration store for most applications.

He goes on to say that it plays a central role in system administration - meaning the Windows system.

Then he drops the bombshell - "..... it is hard to manage."

He thinks the existing tools (apart from PS5) are all limited in one way or another, and/or incomplete in

what they have to offer.

Finally in his short introduction he says this :-

=========================================================================================================

Jones and Hicks have this to say :-

=============================================================================================================

Wikipedia says this :-

=============================================================================================================================================

================================================================================================================================================

PHH - 1st. January 2016.


Navigation - items in the 'Tree'

The Windows Registry is exposed as a "Navigation Provider" when we do our work upon it in PS5.

Lets remind ourselves which Providers exist - try the following on your system :-

Note that 'SQLSERVER' exists, at two items from the end of the list. But this is not always the case,

as we will see in just a noment.

Here is a fuller (better?) look at the Registry related 'PSDrives' from the above list :-

Note how one is for 'local machine' and the other for 'current user'.

Now checkout the following image, where we have gotten the information from a newly launch (started)

PowerShell 'session'. PS_ISE was freshly started and then in that instance the 'Get-PSDrive' cmdlet used

immediately afterwards :-

Yes, the 'SQLSERVER' provider does not seem to be available.

Here is another view of things :-

We need to find out more about this situation ;-0)

There must be a clean and clever way to force the SQLSERVER provider to be available.

Watch this space ................

Lets move on a step or two and see some useful Navigation in action.

Navigation - finding our way around the Registry 'tree' :

PowerShell allows us to navigate the Windows Registry, which like many Windows data stores

is a 'Tree' structure. From root, through branches to leaves - the connections are 'Nodes'.

It is the navigation-based Providers which help us do this, they are HKCU: and HKLM:, and these

are for Current User and Local Machine.

The same cmdlets can be used as with other Providers for navigation.

Here are some BASIC ones :-

Push and Pop may be new to you so try reading the following :-

[ .. as you may imagine 'push' and 'pop' are actions relating to a Stack .. ]

Navigation - Experiment one :

Try this out for yourself ...............

Set the location to 'HKCU' then try the following :-

So above we have moved 'down' the tree structure from the root node into the 'Software' branch.

In the above image we can see 'Belarc' at the bottom - with luck we may be able to creare and

run our own version of a 'Belarc' type program, once we get more experience with PS5.

For those who don't know Belarc, it gives us lots of deeper details of our computer system.

Here is a quick screen shot of a newly downloaded version of Belarc Advisor :-

=============================================================================================================================================

Okay guys, lets now navigate further down the tree (some may say 'up') to another branch, that of "Microsoft".

Check this out in detail :-

All the Names in the long list should belong to Microsoft.

Here (below) are some other from lower in the same list :-

You need to remember that 'Get-Children' and 'dir' / 'Dir' give us the same results - check the following :-

No you can go one branch (and node) further down the tree structure by setting the location to the

'Windows' folder and then asking for children - see below :-

Yes, works just fine as seen in the above image - and what of a branch and node even further ?

Checkout these details :-

[ .. set the required location yourself .. ]

So what about finding where we are currently 'at' in the Registry structure ? Check the following :-

Time to move on, see you in the next sub-section.

PHH - 1st. January 2016.


Location 'Stack' - keeping a track

PHH - 3rd. January 2016.


Registry Keys

I have to personally admit that when it comes to Registry Keys I am well out of my depth, and /or

comfort zone ;-0)

Normally I keep well away from the Registry, hence my ignorance.

However, because of getting to know some more about PowerShell, I will at least dip my toe into the water!

======================================================================================================================================

=============================================================================================================================================

==============================================================================================================================================

===========================================================================================================================================

PHH - 1st. January 2016.


Searching for Software

PHH - 1st. January 2016.


Settings

PHH - 1st. January 2016.


Mappings - old syntax to new cmdlets

cd -

cls -

dir -

sl -

chdir -

pushd -

popd -

PHH - 3rd. January 2016.


Chapter 16 - the filesystem 'Provider' - understanding

Lets start with what guru Ed Wilson has to say in his eBook (red Bible ?) :-

============================================================================================================================

To older guys this Provider looks similar to old DOS commands and BAT files we have seen and used.

Okay it may look like DOS and command shell prompt stuff, but it is still fully object based, and more like .NET

in all reality.

Any similarities in syntax with DOS commands are due to Microsoft providing an under the hood 'mapping'

of old syntax to using the new cmdlet based commanding syntax.

In this chapter, while exploring the FileSystem Provider, we will also put into practice some of the PowerShell

skills and knowledge that we have acquired so far.

Lets use the cmdlet "Get-PSDrive" to see the list of possible Providers :-

Okay then folks, we need to filter some out - all those which are not 'FileSystem'.

But, we hit a snag straight away as the above auto-display would suggest that we were seeing

property values for Provider when we are actually seeing a system processed value (or version)

of Provider - checkout below :-

That's fine folks, but we could do with cleaning up this output ourselves - how about a little string handling ?

Study the details shown below :-

Okay then, the above script does what we need, even though the coding is not that clever!

So when we move into the next subsection (almost immediately) we will see the letters of the

disk/device units being used, like ' C: ', where the colon is VERY important.

See you there ..................

PHH - 6th. January 2016.


What is it ?

In PowerShell a 'Provider' is a software facility which allows us to type commands and script

which when used by the PS 'engine' gives us a tree structured data store to navigate.

We can say that the Provider is 'loaded'. In some ways a bit like a device software driver, sitting

between two 'things' and having information pass in either direction, depending on use.

The FileSystem 'Provider' is actually the basic model on which the others are based or designed.

It is most helpful to know how to use the FS provider as it helps us with the others, but be warned,

there are obviously some differences - but we will comes to these later, or another time and place.

To 'switch' in a Provider we need to use syntax similar to that shown below :-

Code and script before execution :-

And the console 'results pane' shows the prompt after execution, when the Provider is loaded :-

Although we often have many drive letters, as seen below for my system :-

========================================================================================================================

We can in fact only load the Provider for devices/drives with media inserted, or available.

Checkout below how we can ask for a Provider and get some nasty red error messages - first the command :-

And now the results of missing media in the drive :-

So drives J and K have no media and therefore data.

But when we do have an 'active' or available drive/device on which the Provider can operate, we can do this

as seen below (remember good old DOS ?) :-

And the more modern version of this (an alias form) is :-

[ .. 'gci' is an alias for 'GetChildItem' .. ]

And now a third command which is exactly the same, which makes three in total :-

Personally, I will try and use the more modern syntax, as well as using the longer format - it

just makes things some much more meaningful to the reader, and I myself am a reader ;-0)

Notice that the result of Dir, gci, and GetChildItem, is an object - itself an array of objects.

If we wish to see what Type of objects the array items are we can do this below :-

Yes, the 'gm' or 'Get-Member' cmdlet shows us that we have 'DirectoryInfo' objects. This is a

.NET Type and is in the "System.IO" namespace.

We now need to move to the next sub-section in which we will look in detail at 'Navigation'.

See you there ..................

PHH - 6th. January 2016.


Navigation

Put simply, 'Navigation' within a PowerShell 'Provider' is about being able to move up and down the

tree structure of that provider.

The 'Filesystem' provider is the basic one on which the others are modelled.

Also within the Filesystem navigation we are navigating 'Folders', and then finding and accessing

files within those folders.

We soon get the hang of things once we make a few tests and trials. Experimentation and exploration

is a good thing ;-00

Let us start be seeing what I get in my console pane when I launch the PS_ISE applet :-

The default folder shown is "C:\Windows\system32" - we did not have to navigate to this.

Now then folks, lets try some old syntax from DOS days, what does "cd .." do for us ? Check below :-

Yes, see above, we navigate to the parent folder from where we currently are placed.

*** note *** 'cd' stands for "change directory" - but we can't use the longer format :-

Moving on .............

Lets try another way to use the alias, or shorthand syntax 'cd '.

In the following image we see that intellisense tries to help us out :-

Note in the above image we have first moved up another folder level by applying 'cd .. ' a second time.

So when we press return the intellisense assisted command works as expected, check below :-

Okay then folks, lets see how we can check on the contents of a folder in the Filesystem 'Provider'.

For this we need 'Dir', or 'gci', or 'Get-ChildItem' - they are all the same under the hood.

In the above image note that the 'mode' column shows a 'd' attribute for 'Directory' it would seem.

Also above, the Name column shows a folder name and not a file-name.

If we use File Explorer we see the same few folders - check below :-

===========================================================================================================

So what other attributes can we see for Folders/Directories ?

Study the following image to see 'r' and 's' - these are 'System' and 'Read Only'.

Further down the list we have in the console pane, we see that the mode indicates a change of item from folder

to file. And now we also see a file size and a suitable file-name, with secondary file-names like '.bin' and '.log' :-

Lets move on to an alternative syntax, and move away from the older DOS syntax.

In the following image we see we can use 'Set-Location' in place of 'dir' :-

Once again we see above intellisense in action - we are after the 'DriveStore' sub-folder and will see the

results in a short while.

First lets see how we can use 'sl' as a syntax alternative to 'Set-Location' :-

And the result of using 'sl' when we press the return key is this :-

It seems that we have a lot of syntax alternatives (and aliases?) for this basic and fundamental

group of Provider actions / commands.

Now lets return to the 'DriveStore' folder.

Here is what the intellisense gave me when I selected it from the option list :-

Notice the ' .\ ' which was added to my original manual input.

This simply means the current folder.

Here are the results of asking for the contents of this folder :-

It would appear that we only have folders and no files.

And this is confirmed by our use of File Explorer - check below :-

=================================================================================

Before we go any further, lets see what 'cd .\ ' means, or will do for us see below :-

We see first that 'cd ..\ ' moves us back a full directory level :-

But 'cd .\ ' leaves us where we are, not surprisingly.

So now let us see how to find the contents of a folder/sub-folder. Remember the contents

are likely to be both files and folders.

Study the PowerShell way of finding the 'children' of the folder, and displaying them in a grid :-

So for the Filesystem provider the children are directories and files.

Note that in the following image we have clicked the column title bar to force a sort of Z-A and are

looking at near the end of the sorted list :-

Okay then guys, lets now navigate to a different provider. Yes, ' D: ' is a provider but we also know it as

another drive, or device.

Check this out :-

All the usual shorthand syntax and aliases will apply.

And now we can see that we have media in device/drive ' F: ' and so we can navigate there :-

=========================================================================================================

Here is my attempt to navigate through the folder / file structure for the DVD I have just inserted :-

It would appear that I need to learn more, as some of the available files have been ignored by the 'dir' command.

Yes, we get the common ones of '.TXT', 'EXE' and 'PDF' but not the lesser ones of '.ico' for example.

Study the following carefully :-

=========================================================================================================

Oh! we need to know what happens when the DVD/CD medium is removed / ejected.

The following image gives us a clue :-

PHH - 6th. January 2016.


Recursive searching

*** CARE ***

With a recursive search we can create a lot of work, and take quite some time, even on a new and

fast computer, with plenty of power and resources.

We can get the file / folder search with 'Dir' and 'Get-ChildItem' to visit all sub-folders beneath the

current or 'start' folder.

The highest folder is the 'Root folder', the folder in focus is the 'Current folder'.

The folder one above the current folder is the 'Parent folder'.

Any folder below the current folder is a 'Child folder'. So we talk of 'children' when we have multiples.

In the following example, nearly half a million items are found and listed in the console results pane.

YES !!! - nearly 500,000 of them.

Checkout the following details :-

[ .. the image is from the bottom of the list of results - look for the mouse pointer .. ]

Lets move up the very long list to see some intermediate results :-

[ .. notice that the full directory path is shown as a sub-heading .. ]

And now we can move to the very top of the results pane and item list - checkout the command we used :-

Yes, we get a lot of 'Bang' for our command 'buck' of "gci -Recurse".

If we wish to set a filter on the same short search command we can see only the ' .txt ' files as shown below :-

If you check the line count in the lower information 'bar' we see 'Ln' (for lines) is only 1052.

This does NOT mean we have 1052 files, but that the console results output is made up from 1052 lines.

First lets look at the command code/script used :-

I like to use the fuller version of the PowerShell cmdlets as it helps my learning.

Note also that there will be times when restricted access causes some error text output :-

Since I don't yet know how to get around this restriction we can just ignore it for the moment.

Let us now focus our attention on counting the actual text files found, not the display output lines.

Study the following images details carefully :-

Yes, as I thought, a lot less, we only have 486 files.

Lets get the results in a handier format, and one where we can apply filters and constraints etc. :-

With all our 486 items in the 'GridView' we can move from the top of the list to the very end - see below :-

Now we can apply our constraint of the file length (size) being over a minimum vale of 230,000 bytes.

Study these details - the full resultant list is shown :-

And finally, lets do the same search from the current folder once it is set to being the 'Root folder'.

So in effect we are finding all the text files on the C: drive of my desktop - check this out :-

Oh! - YES !! - that is more like it ;-0)

6654 in total on drive C:

Try adding a few script lines to time how long the search takes ;-0) And include drive / device D: as well.

I will give it a go to see what I can do.

Here below is an example of timing how long it takes to find all the PDF files on my drive D:

As you can see below we only find 64 and it takes 1.5 seconds, roughly.

So lets now simply comment out part of line 5 and change the script to be able to find out all files on drive D:

D: is my data drive, where I make and place Virtual Machines and databases, so there are many fewer files than

on drive C:

Checkout these details :-

Yep! - above takes less than three seconds.

However, as you can see below, there is much less stored on drive D: at the moment :-

======================================================

Here is a snapshot of the Root folder of my D: drive :-

==========================================================================

Moving on a step or two ....................

SQL Database files :

Lets adjust our script code to allow us to find ' .mdf ' files which are database files for SQL Server.

Study the code below, AND, if you are really good, you will see a small issue which needs changing ;-0)

Checkout all the details :-

Note that the highlighted lines are actually ' .bak ' files and NOT ' .mdf ' ones.

Line 5 above needs a change from ' *mdf* ' to ' *mdf ' and so the last ' * ' is dropped. This should help a lot.

Here below is another section of the same results set - notice the last line, it is one we need to NOT count.

Okay then folks, lets run the altered code to get a refreshed count of only the ' .mdf ' files - here is the code :-

Arrrh ! - that's better we have lost (dropped) the five files which were really .bak and not .mdf ones.

And below the same code produces the results item Grid with the highlight indicating where one previous

entry is now missing :-

Lets move on do bring the sub-section to an end ...........

Final example - finding the number of .BAK files on both drives D: and C:, and the time taken to find them,

which includes displaying them as well.

Well, above shows that in less than 3 minutes my 1 TB drives of C: and D; can be searched and all backup

files found and counted.

Oh! - I should have said, the sorting of the Length column allows us to see that six or seven files take up a lot of room.

In another section we can find the LARGE backup files using our own script code.

Enough of this messing around for now - see you in the next sub-section...........

PHH - 7th. & 8th. January 2016.


Starting to use it

Okay folks, let us start with the results for a change ;-0)

Let us see the next image in which we have the six largest files of secondary filename ' .bak ' and

their Fullname - which is the Directory / Folder name and the filename - in one.

======================================================================================================================================================================

The first thing to realise is that in order to get the 'FullName' property displayed we needed to specify

in a 'Selection' clause the exact properties we required.

Here is what I specified in the script code :-

======================================================================================================================

And if we reduce the width of the display GridView object we see all these properties

listed in the column headers - check this thoroughly :-

==================================================================================================================

And now it is time for us to look through the script code.

I have tried to reduce (or shorten) the lines of code so that it is more compact than

I would usually write it, so take a careful look at the details :-

It would appear that we do not have any large backup files on drive D:

However, we do have some small ones - see the next image :-

And now we can see the code for the script - which is hardly changed from that we used to find the

larger files - check this out below :-

If we use intellisense we can see some of the properties available to us for the Type of object we have

in the items list gathered by the conditional search.

The items are objects of type 'System.IO.DirectoryInfo'. Check some intellisense entries :-

====================================================================

And a few more members - properties and methods :-

====================================================================================================================

We seem to have not captured / 'Name' and there may be another one or two as well.

So to see everything about the class being used lets call on Help Viewer 2.2 - see below :-

===============================================

And here is a full and complete list of the class properties :-

==============================================================================================================================================

Yes, a lot more than the few we get by default ;-0)

Most often we will need a full path - for folders and files.

Time to move on, lets go to the next sub-section and learn some more PowerShell 'stuff'.

PHH - 6th. & 8th. January 2016.


How to create new items - files, folders, profiles

Very often we guys will be writing script code to retrieve information for display and use.

And with the 'Filesystem Provider' we have dealt a lot with that side of things already.

However, there are times when we need to create new versions of 'things', new items. In the Filesystem

that is most likely to be a folder (directory) or a file.

In PowerShell we have a VERY flexible, and useful, cmdlet called 'New-Item'.

The New-Item command-let allows us an easy way to make items not just in the Filesystem provider,

but in other providers as well.

Folders :

Before we start this small section, we need to look at a couple of tips that Jones and Hicks have to say.

We need to know of the 'mkdir ' command even though we may not use it much, or at all.

Remember that the PowerShell way is by using 'NewItem' which is a cmdlet.

Study the following details :-

=====================================================================================================

=================================================================================================================

So to summarise this PS has a function called ' mkdir ' which under the hood uses the cmdlet called New-Item with

some sort of an input parameter which indicates that it is a directory which is required.

Lets at least give this a go once, even if then afterwards we use the PowerShell way and cmdlet.

Check this details :-

And now this which is the result of running the command :-

Now we can check to see if we can use the new folder / directory :-

[ .. first the command .. ]

And now the image of the result of running it :-

Yes ! - it all looks fine and a-okay ;-0)

And to prove what we have done lets use File Explorer - see below :-

=======================================================================================================

Moving on a step or two ...............

Doing it the PS5 way :

Okay then folks, lets do it the full PowerShell way - make a new directory / folder that is.

Lets see what help has to say before we experiment ourselves - check this out :-

Okay guys, I think we can have a go ourselves.

Lets try to make a new sub-directory in the root Temp folder ( C:\Temp ) - check below :-

And looking for the result we can use another PS command - check this out :-

And here is an alternative way to do the same thing - create a new directory / folder :-

And now "Multiple" directories :-

==============================================================================================

'Real-time' command line entry :

Getting things right :

================================================================================================

Files :

Profiles :

PHH - 6th. & 9th. January 2016.


FILES - find, open, copy, display, add to, delete etc..

PHH - 6th. January 2016.


Advanced tasks

PHH - 6th. January 2016.


Some example scripts

PHH - 6th. January 2016.


Shorthands and Aliases

Change / Move :

cd

set-location

sl

==============

Make / Create :

PHH - 8th. January 2016.


scritp and code

=============================================================================

Set-Location C:\windows\system32

$my_ResultsTXT = gci -Recurse | Where-Object -Filter {$_.Name -like '*.txt*'}

"Total number of TXT files :- " + $my_ResultsTXT.length.ToString()

$my_ResultsTXT | Out-GridView

=============================================================================

$my_StartDT = [DateTime]::Now

Set-Location C:\

$my_ResultsC = gci -Recurse | Where-Object -Filter {$_.Name -like '*.bak'}

"Total number of BAK database files (C:) :- " + $my_ResultsC.length.ToString()

Set-Location D:\

$my_ResultsD = gci -Recurse | Where-Object -Filter {$_.Name -like '*.bak'}

"Total number of BAK database files (D:) :- " + $my_ResultsD.length.ToString()

$my_Results = $my_ResultsD + $my_ResultsC

$my_Results | Out-GridView

$my_EndDT = [DateTime]::Now

[TimeSpan]$my_TimeTaken = $my_EndDT - $my_StartDT

"Time taken :- " +$my_TimeTaken.ToString()

=============================================================================

$my_StartDT = [DateTime]::Now

Set-Location D:\

$my_Results = gci -Recurse #| Where-Object -Filter {$_.Name -like '*.pdf*'}

"Total number of ALL files (D:) :- " + $my_Results.length.ToString()

$my_Results | Out-GridView

$my_EndDT = [DateTime]::Now

[TimeSpan]$my_TimeTaken = $my_EndDT - $my_StartDT

$my_TimeTaken.ToString()

=============================================================================

$my_StartDT = [DateTime]::Now

Set-Location C:\

$my_Results = gci -Recurse |

Where-Object -Filter {($_.Name -like '*.bak') -and ($_.Length -gt 230000)}

Set-Location D:\

$my_Results += gci -Recurse |

Where-Object -Filter {($_.Name -like '*.bak') -and ($_.Length -gt 230000)}

$my_Results |

Select-Object FullName, Length, Mode, Extension, DirectoryName, CreationTime |

Out-GridView

"Time taken :- " + ([DateTime]::Now - $my_StartDT).ToString()

"Larger files :- " +$my_Results.Length.ToString()

=============================================================================

$my_StartDT = [DateTime]::Now

Set-Location C:\

$my_Results = gci -Recurse |

Where-Object -Filter {($_.Name -like '*.bak') -and ($_.Length -lt 1300)}

Set-Location D:\

$my_Results += gci -Recurse |

Where-Object -Filter {($_.Name -like '*.bak') -and ($_.Length -lt 1300)}

$my_Results |

Select-Object FullName, Length, Mode, Extension, DirectoryName, CreationTime |

Out-GridView

"Time taken :- " + ([DateTime]::Now - $my_StartDT).ToString()

"Smaller files :- " +$my_Results.Length.ToString()

=============================================================================

PHH - 8th. January 2016.


Chapter 17 - running PS scripts from C# and Vulcan

Okay you guys, running a PowerShell script from within a .NET application - either C# or Vulcan for us.

This is quite easy, as well as rewarding in a developer's sense of things.

However, the biggest problem to us will be the returned objects from the PS engine.

As I explained much earlier in these eNotes, if we are not totally 100 % sure of the object(s) we are dealing

with from returned commands and pipelines, then we can get into a right pickle (mess).

This is the case here with having data returned from our scripts being run by PS.

So we need to take this one step at a time, firstly starting with the codeproject example for at the

following URL / link :-

http://www.codeproject.com/Articles/18229/How-to-run-PowerShell-scripts-from-C

I have downloaded this oldish sample and gotten it working in Visual Studio 2015. Checkout bellow :-

[ .. the example ran immediately in my VS installation, no issues at all .. ]

======================================================================================================================

A very relevant section of the eNotes is seen below, and this tells us how to find the necessary DLL file that

we require before we can run our own apps.

We need an assembly to add to our References in the SE (solution explorer) pane.

Here is what I found :-

========================================================================================================================

Yes, once we find and employ the correct assembly then we can add the namespace references at the head of our

application / project code, see above - last two of the three shown.

The next image shows the working code from the example :-

=============================================================================================================

Please realise that when the application sample runs we can change the script to whatever one we wish.

However, it is a good idea to use work and successful scripts.

Below is another simple command script, chosen by myself :-

================================================================================================

The above example is nice as it does not produce millions of output lines.

It may interest you to see that a script of two commands, not even pipelined, does produce the

two sets of returned data we may well expect :-

================================================================================================

So what assembly reference exists in the downloaded sample which may be needed by us for all

of our own apps ? Checkout the following image details :-

===================================================

Yes, where do we find the 'System.Management.Automation' assembly ?

I have used the properties option to indicate the Path - see below :-

==================================================================================================================================

We will see in the next few sub-sections, how to find and use this assembly.

Once we have it we can then add lines to our own code and samples - as see below :-

==================================================================

Lets now move on to see how to make our own WPF apps.

First we will simply try to copy the WinForms older sample.

See you in the next sub-section .............

PHH - 31st January 2016.


Getting the .NET references & classes etc.

When we start a new project which is based on the WPF template, we see that the

References section is as seen below - missing the 'System.Management.Automation'

assembly reference - check this out :-

=======================================================

So before we can add the reference to the required assembly we need to locate it on our file system.

Look at the following details on my Windows 10 system :-

======================================================================================================================================

Notice that we are in the dialog screen for adding references - that is assemblies to you and me ;-0)

So lets choose the correct one we need below, and continue :-

=====================================================================================================================================

Then make sure that you select the new reference as shown below, taking care NOT to de-select any others :-

========================================================================================================================================

We can check to see if all has gone OK by trying to add a namespace at the head of our project code :-

=======================================================================

Also we should see the new reference appear as seen in the following image :-

====================================================

And now, finally, we can add a few lines of .NET code to test out that we are doing the right things.

The code shown below simply creates and opens a 'Runsapce', the basic PS object for running a

script from C# or Vulcan.

Checkout lines 19 through 28 below :-

============================================================================================= =====

At the point shown above, we have a 'bear-bones' or skeleton application.

We can now gets working scripts from wherever, and then run them in order to get returned data 'results'.

However, remember we need to know just exactly what objects we are dealing with in the returned data

set, so that we can handle them appropriately, and then display selected parts of the 'set' in our WPF

UI elements.

Now that we know just how to set-up a PowerShell and WPF application, lets move on to make our

first sample.

It will start off as our own WPF version of the original codeproject WinForms sample, then we will improve

things and explore new avenues etc., etc..

See you in the next sub-section ......................

PHH - 2nd February 2016.


Simple - Results display - C#

I am using C# here just as a handy place to start coding.

Once we get the hang of things, and see just what is necessary, we can easily move over to trying

out Vulcan.NET - no probs!

========================================================================================

=========================================================================================================

===========================================================================

===============================================================================

===============================================================================================================

==========================================================================================================================

PHH - 1st. February 2016.


working script and code

==========================================================================

using System.Windows;

using System.Management.Automation.Runspaces;

using System.Collections.ObjectModel;

using System.Management.Automation;

using System.Text;

using System.ComponentModel;

namespace WPF_with_PowerShellCologne2016

{

public partial class MainWindow : Window,  INotifyPropertyChanged

{

private string _scriptText = "Get-Process";

private string _results;

public string ScriptText

{

get { return _scriptText; }

set { _scriptText = value; NotifyPropertyChanged("ScriptText"); }

}

public string Results

{

get { return _results; }

set { _results = value; NotifyPropertyChanged("Results"); }

}

//----- events -----

public event PropertyChangedEventHandler PropertyChanged;

public MainWindow()

{

InitializeComponent();

this.DataContext = this;

//----- POSSIBLE issue !? -----

//----- out of the box this app will produce errors for cmdlets -----

//----- added to the PS5 update - we need to makes changes to -----

//----- allow all current PS5 commands in Windows 10 to work. -----

}

//----- methods -----

public void NotifyPropertyChanged(string propertyName)

{

if (PropertyChanged != null)

{

PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

}

}

private string RunScript(string scriptText)

{

Runspace runspace = RunspaceFactory.CreateRunspace();

runspace.Open();

Pipeline pipeline = runspace.CreatePipeline();

pipeline.Commands.AddScript(scriptText);

pipeline.Commands.Add("Out-String");

Collection<PSObject> results = pipeline.Invoke();

runspace.Close();

StringBuilder stringBuilder = new StringBuilder();

foreach (PSObject obj in results)

{  stringBuilder.AppendLine(obj.ToString()); }

return stringBuilder.ToString();

}

private void button_Click(object sender, RoutedEventArgs e)

{

//--- not local must be class variable ---

Results = RunScript(ScriptText);

}

}

}

==========================================================================

<Window x:Class="WPF_with_PowerShellCologne2016.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        xmlns:local="clr-namespace:WPF_with_PowerShellCologne2016"

        mc:Ignorable="d"

        Title="Cologne - PowerShell from WPF :" Height="350" Width="620" Background="Cornsilk">

    <Grid>

        <TextBox Background="Thistle" Width="592" Height="65"

                 Margin="10,22,0,0" AcceptsReturn="True"

                 TextWrapping="Wrap" Text="{Binding Path=ScriptText, UpdateSourceTrigger=PropertyChanged}"

                 HorizontalAlignment="Left" VerticalAlignment="Top"/>

        <Button x:Name="button" Content="Run Script" Height="21"

                Margin="10,92,0,0" VerticalAlignment="Top" Background="LightBlue"

                Click="button_Click" HorizontalAlignment="Left" Width="85"/>

        <TextBlock HorizontalAlignment="Left" Height="176" Margin="10,133,0,0"

                   TextWrapping="Wrap" Background="LightBlue"

                   Text="{Binding Path=Results, UpdateSourceTrigger=PropertyChanged}" />

    </Grid>

</Window>

==========================================================================

<Application x:Class="WPF_with_PowerShellCologne2016.App"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:local="clr-namespace:WPF_with_PowerShellCologne2016"

             StartupUri="MainWindow.xaml">

    <Application.Resources>

    </Application.Resources>

</Application>

==========================================================================

using System;

using System.Collections.Generic;

using System.Configuration;

using System.Data;

using System.Linq;

using System.Threading.Tasks;

using System.Windows;

namespace WPF_with_PowerShellCologne2016

{

/// <summary>

/// Interaction logic for App.xaml

/// </summary>

public partial class App : Application

{

}

}

==========================================================================

PHH - 2nd February 2016.


Simple - Results display - VN

Simple - Results display - C#

PHH - 1st. February 2016.


Handling returned Objects - C#

==================================================================================================

===========================================================================================

PHH - 1st. February 2016.


Handling returned Objects - VN

Handling returned Objects

PHH - 1st. February 2016.


Asynchronous execution - scripts from C#

http://www.codeproject.com/Articles/18409/Asynchronously-Execute-PowerShell-Scripts-from-C

PHH - 6th. February 2016.


Chapter 999 - sample scripts / commands

PHH - 6th. December 2015.


General test samples

#get-wmiobject win32_printer | Out-GridView

# get-printer

# get-printer | Out-GridView

get-wmiobject win32_printer `

| sort Name `

| select Name, Comment, DriverName, Location, Network, PortName, ShareName `

| Out-GridView

<#get-wmiobject win32_printer `

| sort Name `

| select Name, Comment, DriverName, Location, Network, PortName, ShareName `

| Out-GridView

#>

# Get-Date

# Get-PrinterDriver | select Name

<# get-process |

select -first 13 |

select -last 7 |

select ProcessName, Id, Handles

#>

# Get-Command | Where-Object -filter {$_.CommandType -like '*cmd*'}

<#

cd \

$my_Cmds = Get-Command

$my_Compare = ""

$my_BuildString = ""

foreach($cmd in $my_Cmds)

{

if($cmd.CommandType -ne $my_Compare)

{

$my_BuildString += ($cmd.CommandType.ToString()+',')

$my_Compare = $cmd.CommandType

Write-Host $my_Compare

}

}

"============================================================="

$my_BuildString

#>

<#

$my_Cmds = Get-Command *Get-* | Where-Object -filter {$_.CommandType -like '*cmd*'}

"`n`nThe number of 'Get' cmdlets is :- "+$my_Cmds.Length

#>

<#

Set-Clipboard "this is old stuff !?"

Get-Clipboard

Set-Clipboard "the old stuff has been replaced ........."

Get-Clipboard

#>

<#

$my_Printers = Get-Printer

Set-Clipboard $my_Printers

$my_returnedPrinters = Get-Clipboard

"`nMy returned details :- number of items : "+ $my_returnedPrinters.Length.ToString()

#>

<#

$my_MusicPath = [Environment]::GetFolderPath("MyMusic")

"`n`ntest path is :- "+ $my_MusicPath

#>

# Get-Command *history*

# Get-History

# Get-Command *-Object

#Get-Command | Where-Object -filter {$_.Name -like '*-Object'}

#Get-Command | Where-Object -filter {$_.Name -like '*-Object'} | select Name, Version, CommandType

<#

Get-Verb

Get-Verb | Sort-Object -Property Verb -Descending

#>

<#

Get-Verb |

Select-Object -Property Group -Unique |

Sort-Object -Property Group

#>

<#

Get-History | Out-File -FilePath "C:\Temp\HistoryISE_01.txt"

$my_StoredHistory = Get-Content "C:\Temp\HistoryISE_01.txt"

$my_len = $my_StoredHistory.Length

$my_len

$my_StoredHistory

#>

<#

Test-Path "C:\Temp\"

Test-Path "C:\Temp\HistoryISE_01.txt"

#>

<#

Set-Location C:

Get-ChildItem

#>

# Get-PSDrive

<#

Set-Location HKCU:

Get-ChildItem

Set-Location HKLM:

Get-ChildItem

#>

<#

Set-Location variable:

Get-ChildItem

#>

<#

Set-Location variable:

Get-ChildItem | Where-Object -Filter {$_.Name -like '*my_*'}

#>

<#

[DateTime]$StartDT = [DateTime]::Now.Date

[DateTime]$EndDT = [DateTime]::Now

[TimeSpan]$TimeTaken = $EndDT - $StartDT

"`n .. time taken .. $TimeTaken"

#>

#Get-Random -Maximum 139 -Minimum 49 -SetSeed 191

<#

$my_RootAns = [System.Math]::Sqrt(13)

"our answer is :- $my_RootAns"

$my_ChopVal = [Math]::Truncate($my_RootAns)

"`nOur chopped off answer :- $my_ChopVal"

#>

#====================================================================

#winver

#[System.Environment]::OSVersion.Version

#(Get-WmiObject -class Win32_OperatingSystem).Caption

#(Get-ItemProperty -Path c:\windows\system32\hal.dll).VersionInfo.FileVersion

#$my_Drivers = Get-WindowsDriver –Online -All

#$my_Drivers.Count

#$my_Drivers | get-member

#$my_Drivers | Out-GridView

$my_Drivers | where -filter {($_.ClassName -notlike 'System') -and `

($_.ClassName -notlike '*Net*') -and `

($_.ClassName -notlike '*Class*')}

$my_Drivers | where -filter {($_.ClassName -notlike 'System') -and `

($_.ClassName -notlike '*Net*') -and `

($_.ClassName -notlike '*Class*') -and `

($_.BootCritical)}

$my_Drivers | where -filter {($_.ClassName -notlike 'System') -and `

($_.ClassName -notlike '*Net*') -and `

($_.ClassName -notlike '*Class*') -and `

($_.BootCritical) -and `

($_.InBox)}

#=================================================================

PHH - 12th. April 2016.


Chapter 0 - scripts 'n' code

PHH - 6th. December 2015.


Chapter 1 - scripts 'n' code

PHH - 6th. December 2015.


Chapter 2 - scripts 'n' code

PHH - 6th. December 2015.


Chapter 3 - scripts 'n' code

PHH - 6th. December 2015.


Chapter 4 - scripts 'n' code

PHH - 6th. December 2015.


Chapter 5 - scripts 'n' code

PHH - 6th. December 2015.


Chapter 6 - scripts 'n' code

PHH - 6th. December 2015.


Chapter 7 - scripts 'n' code

PHH - 6th. December 2015.


Chapter 8 - scripts 'n' code

PHH - 6th. December 2015.


Chapter 9 - scripts 'n' code

PHH - 6th. December 2015.


Chapter 10 - scripts 'n' code

PHH - 6th. December 2015.


Chapter 11 - scripts 'n' code

PHH - 6th. December 2015.


Chapter 12 - scripts 'n' code

PHH - 6th. December 2015.


Chapter 13 - scripts 'n' code

PHH - 6th. December 2015.


Appendices

PHH - 6th. December 2015.


Appendices - All (A - Z)

PHH - 17th. November 2015.


Appendix 'A' - common terms and acronyms

LHS - left hand side

RHS - right hand side

WMI - Windows Management Instrumentation (facilities)

GUI - Graphical User Interface

ISE - 'Integrated Scripting Environment'

PS - PowerShell

PS5 - PowerShell version 5.0

WMI - Windows Management Instrumentation

'cmdlet'- (said command let) is a PS command-line utility - it seems to be unique to PS.

[ .. these exist only in PS and are written in a .NET framework language .. ]

VM - virtual machine

O/S - operating system

IDE - Integrated Development Environment

VIDE - Vulcan IDE - Vulcan Integrated Development Environment

HKEY - "Handle to Registry Key"

PHH - 30th. October 2015.


Appendix 'B' - Tips and Tricks and Transcription

Using the " -WhatIf " parameter switch :

Preserve you 'state' of your system while you do a test with your trial script code.

Put this in your own Functions - make them Advanced Functions ;-0) See Appendix 'F'.

http://www.techrepublic.com/blog/10-things/10-powershell-commands-every-windows-admin-should-know/

====================================================================================================================

1: Get-Help

2: Set-ExecutionPolicy

3: Get-ExecutionPolicy

4: Get-Service

5: ConvertTo-HTML

6: Export-CSV

7: Select-Object

8: Get-EventLog

9: Get-Process

10: Stop-Process

Launching Help Viewer 2.2 as a separate (stand alone) application :

Setting up your task bar to launch the 'Help Viewer' tool from Microsoft can be a bit tricky.

"Easy when yo know how ! "

Here is what I just managed to do :-

==============================================================================================

I first got the idea of the extra parameter to use from the following link / URL

https://social.msdn.microsoft.com/Forums/en-US/9baf2e24-c00c-48ff-953b-83d722ea0638/call-helpviewer-21-outside-visual-studio-2013

This is what now works for me :-

[ ..we will look at how to change the Properties dialog and tabs in just a moment .. ]

Target :

"C:\Program Files (x86)\Microsoft Help Viewer\v2.2\HlpViewer.exe" HlpViewer .exe /catalogName VisualStudio14 /locale en-us /launchingApp Microsoft, VisualStudio ,14.0

This is in two parts :- the application EXE and then the parameter :-

"C:\Program Files (x86)\Microsoft Help Viewer\v2.2\HlpViewer.exe"

HlpViewer .exe /catalogName VisualStudio14 /locale en-us /launchingApp Microsoft, VisualStudio ,14.0

Start in :

"C:\Program Files (x86)\Microsoft Help Viewer\v2.2"

Pin to Taskbar :

If you wish to pin the launch icon for Help Viewer to the Taskbar or Start screen then find the EXE file using File Explorer

and the right click to bring up the context menu - see below for some helpful guidance details :-

=================================================================================

The full 'correct' path is seen below :-

==================================================================================

And when you locate the correct file you will see something like that shown below, depending on the actual

version of the 'Viewer' you require :-

=================================================================================================================

Now right click for the context options - find pin to Taskbar towards the bottom of the menu choices, and pin to Start nearer

the top of the options list :-

============================================================================================================

In order to make the icons work for you you will probably need (like me) to provide some extra information

to the entries already in the Properties pane for "Help Viewer 2.2"

Go to your 'pinned' icon and locate the Properties option - see next image :-

Then when the Properties dialog is shown, select the 'Shortcut' tab and make sure the two entries

for 'Target' and 'Start in' are correct.

** top tip ** it is most likely that you have the parameter sting (shown way above) missing from the

end of the string for pointing to the EXE full path.

Also make sure that you have your version of the Visual Studio installation available to you on your

Windows platform.

Check this out below :-

==============================================================

Now you should be good for just clicking once in the Taskbar icon and launching Help Viewer 2.2

or whatever you version choice.

*** Top Tip 2 ***

A deep seated problem / issue with Windows from years back !

Icons not showing their chosen or selected image / picture - this has been ongoing in different parts

of the Windows environment for years. Quite often it can be rectified by a 'double trick' ;-0)

In our current situation, the icon is likely to have its 'picture' showing the default or blank image - see below :-

Right click the 'HlpViewer' item shown above to bring up the next context menu - see below :-

Click to open up the Properties pane and choose the 'Shortcut' tab :-

===================================================================

It is the Change Icon button that you need to click next :-

=============================================================

When you select the Change Icon button with a click, a dialog screen opens as

seen below :-

======================================================

Now then folks - the trick - select the icon / image and click OK. Then back at the Properties

dialog click 'Apply' and then 'OK'.

After doin g the above no change of icon appears to have taken place - that is normal, now do

exactly the same thing again - selecting the icon image and applying etc.

After doing this twice in a row, for some reason, the icon shows as we would like - see below :-

Yes, the icon is there in both the Taskbar and the pop-up menu.

Good Luck ;-0)

PHH - 30th. October & 17th. November 2015.


Making and Referring to Transcripts

In terms of using PowerShell, a "Transcript" is the details placed into a text file of the full recorded history of

a PS session with ISE or the Console.

It is more than what we get with the 'History' of a PS session, which in itself is transient in nature unless we

make the effort to save it to file. In Transcript files we get all the input and output (results) of a PS session.

Here is what we get from a request for 'History' :-

But here is the same related Transcript detail from the growing file on disk :-

Obviously there is a lot more detail in the Transcript file.

Now then, we are going on to see below that I have my desktop development PC system set-up to automatically

start a 'Transcript' session each time I launch the ISE shell or the Console. This means I have full details recorded on file

of everything I have done for days and weeks - quite a useful record for me writing eNotes.

Lets see how we can find my existing Profile :-

And lets see if the actual named file exists :-

So since the file exists lets now see how to open it and read its content :-

As you can see in the image above, line 5 is the command which starts the new Transcription, each time a

session is begun.

Lets now see that start (if not the top, or first few lines) of such a file from just a few minutes ago :-

Above we are seeing the first input output captured from my keyboard input.

Now we can go on to see below what the very file headers look like :-

=======================================================================================================

Okay - this all makes sense, but what about the whole bunch of such files that accumulate over time, and

many sessions ?

Here is a snap-shot of my File Explorer - the file in focus is the one we saw parts of above :-

============================================================================================================================

And here below is some information which is provided from the PS help system - check it out generally :-

PHH - 2nd. December 2015.


Appendix 'C' - comments and remarks in Scripts

PHH - 30th. October 2015.


Appendix 'D' - MS-DOS from 1991 (version 5.0)

PHH - 30th. October 2015.


Appendix 'E' - using 'escape' sequence

There are times in every programming language code, or script sections, when we wish to use

a text character for just what it is - the original text character.

Most languages and scripts, as well as Regular Expressions, have characters reserved for special

purposes.

These will therefore need some simple way of us showing to a compiler or interpreter type of software

engine, that we require the 'specialness' of the character to be calmed or nullified.

This general technique is called 'escaping', and we talk of escape characters.

Many of us will be familiar with escaping in XAML and .NET, but we need to now make sure that we all

know how to 'escape' when doing PowerShell.

The easiest way to do this is to use the in-built HELP from PS itself - check the following :-

[ .. after checking, we will carry out some basic testing with commands and 'cmdlet's .. ]

PHH - 4th. November 2015.


Appendix 'F' - creating and using Functions

This is a VERY important part of PowerShell work.

Experienced PowerShell guys use Functions all day long, and this includes many of their own

making as well as those existing in the PS engine / system.

We all need to be aware of what system functions are available to us, as well as how to create

our own - from simple ones to much more complex ones.

Although Functions can be large - VERY large - it is probably not a good idea to make then so ;-0)

Design your functions to be relatively small to medium bunches of script, doing a VERY specific task

if you can manage it that way.

I also suggest that you try NOT to design things so you need too many input parameters either.

Rule ONE seems good - "try to keep things simple".

Rule TWO - make the function discrete, so it does NOT interact with outside of itself. Have in only accept

data parameters (or not) as well as returning other data values. Yes, it can and may get data from the PS system

using cmdlets etc..

Finally, 'Rule THREE' - this says try to find out the accepted PS way of designing and using functions.

Do not try and do things your way, and a way different to what others expect from PS scripts.

At least check out Ed Wilson before you do anything - buy a copy of hie excellent eBook.

Before we move on here is my attempt to show you what can be done, and keep it simple at the same time.

Check the following image - see below for full details :-

Please do NOT worry about the statistical significance of the 'Maths' ;-0)

We have one function calling two others and the two being called are used as values on line 15.

Whoops ! - something looks wrong with the arithmetic !? And checking the colour of the syntax items

on line 15, we have certainly done something wrong - our answer is half of the largest ;-0((

Lets try again with our trial syntax on line 15 - see below :-

Arrrh !! - that looks better, as both function calls are the same colour, AND the result is half of 140.

Much more like it - however, you will need to be able to recover in this way as you do your own scripting.

Lets move on ........................

PHH - 5th. December 2015.


What is a Function !?

Lets try to keep this as simple as possible, and also as simple as it really is.

Firstly, in PowerShell there are Functions and nothing else like subroutines or procedures.

A function is a discrete 'parcel' of script doing a specific task or job.

However, the big thing about functions is that they can be used as 'values' and therefore scripted

'in-line' with the other parts of our command lines.

Once we get our heads around the fact that Functions can be used as values, we also need to know

that the call to the Function can require input values (termed parameters) or not. Depending on the

type of function we have created.

Functions are found a plenty in the PS support system, and are created in large numbers by practising

professional PS administrators.

Most experienced guys make their own Function libraries, a bit like many of us did in VO days ;-0)

Let us now look at some function code I have put together for demonstration purposes. It is not particularly

'clever' code but is sufficiently correct to be able to show a few things.

Below are two functions which require a pair of input parameters, so the script lines at position 29 and 33

show us how to call on the various functions - check this out carefully :-

So in effect, above we have one line of program (execution) code and three function definitions.

Line 33 is our 'execution' section.

Lets tidy up a few lines and make things more compact etc. :-

Above, line 19 has had a change of syntax, just to try something slightly different.

Okay folks, lets move on, see you in the next sub-section ......................

PHH - 5th. December 2015.

Addendum : How to find our Functions for the session :

It is sometimes useful to be able to identify which Functions we have used in a session.

Lets try an experiment or two - check below :-

We can see highlighted above (not very well) the 'get-lowest' function of our own making - there is no version of source

column data.

But if we rename our functions in a way similar to out variables, with prefix of 'my_' then we can easily find and

display them as we see in the next image - seen below :-

Obviously I had to rename the functions and then re-run the scripts from earlier in the sub-section.

Until we restart the session the earlier function names will still be in the displayed lists.

PHH - 5th. December 2015.


Getting started with script / code

The following image and URL / link may be helpful to you :-

https://technet.microsoft.com/en-us/library/hh847829.aspx

https://technet.microsoft.com/en-us/magazine/hh360993.aspx

==========================================================================================================================================

Lets now move on to do some 'creating' !!

=======================================================================================

Using Functions we can package blocks of closely related commands, into a single unit that can be accessed by name.

"Functions can return values that can be displayed, assigned to variables, or passed to other functions or 'cmdlet's. "

Functions may also be written to pass back values to the calling script.

Functions do a very specific task, or job. They do not need to pass-back any values, but commonly do.

Lee Holmes in his eBook "Windows PowerShell Pocket Reference, Second Edition" has this to say :-

=================================================================================

We obviously need to look more into the use of $input and $args.

I have written a suitable simple function of my own, so it can be used to show many of these

features for you - note I developed it stage by stage, building up to the final things. Yes, it was

a bit tricky getting the syntax right and trying to interpret web articles which were only partly

complete.

Study the following image details VERY closely :-

The $Input approach :

The $Args approach :

Providing Input Data - how to specify - the syntax to use :

In the following function from Ed Wilson, checkout line 6 from where we call the function.

We specify the input parameter with a leading '-' (minus) sign, followed by its value. The order of the parameters

does therefore not matter, which is a bit of a relief to the designer / scripter guy.

Check these details below (lines 1, 6 and 7 in particular :-

Okay then folks, let us now carry out an experiment with the input parameters of Ed's function.

Let us reverse the order of their input, so we provide computer before drive - checkout the following :-

Having adapted Ed's nice function for the purposes of learning by experimenting and exploring, lets now process

the output better than we are above.

It appears as though the output of 'Get-DiskSpace' is now an array with two elements.

We can access these two item values and process the individual output as seen below :-

Notice in particular lines 1, 8 and 13 in the above image.

Lets move on .............................

PHH - 3rd. & 16th. November & 5th. December 2015.


More complex Functions

We are going to take this opportunity to look at how we can provide data as parameters for our

Functions - parameters in different formats for essentially the same functions.

As you will realise by now, if we design coding experiments, and explore all possible aspects of code

and script syntax, then we learn much, much more 'stuff'.

Let us now see how the PS system '$Args' variable can be used to provide a list (or bunch) of items as

parameter input. Check out the first two functions - their syntax changes - and also how they are called

from line 29 shown below :-

Do please notice that the list of data items making up the parameter do NOT have separating commas.

Within the function code this list of data items is seem as a collection called ' $Args '.

Lets now try and develop and change the code so that the script section is tidied and reduced in size,

the basic operation is still the same as it stand :-

Now then folks, we need to change the script structure so that we can pass the listed data as parameters into the third of our functions.

But since I have gotten on screen a good example of a 'gotcha' I want to share it with you.

Below we see that an extra ' , ' (comma) has caused me great grief and broken the execution.

In the line 35 see the separating comma between the Hi & Lo list 'P' variables :-

There was not much indication at all that things were untoward - BUT - nasty red stuff when I tried a code run.

Below is the offending line 35 without highlighting, and large and clear enough for us to see the offending ' , ' in line 35.

================================================================================================================================

So let us now remove the comma and hopefully get some results.

In the code shown below we now have the data lists being made in the program section of our code.

The third function has array parameters - study thoroughly this improved version of our script :-

Lines 23 through 35 are what we are particularly interested in above.

And it we now collapse the function code area we have a simple program execution code section of lines 32 - 35.

And you will see that after all these changes and improvements we still get the same answer of 87 ;-0)

Time to move on ..................

PHH - 5th. December 2015.


Positioning Parameters

Once we start to use Functions with parameter inputs we realise that there is a definite need to have some

firm control over the order in which we provide input data as parameters.

Take this recent example shown below, we have two inputs required and getting them the wrong way around

will certainly give us the wrong answer - as far as our rather trivial example is concerned.

Study what we have - check below :-

===============================================================================

Let us now see some script code which calls the 'average' function in the correct manner - or the

way I designed it to be (line 35 is the focus line ... ) :-

Okay, so when we get our inputs the right way round the answer is 87.

Let us now see how easy it is to get the 'wrong' answer, simply be swapping over the input data - check line 37 below :-

Yep! - as we may have guessed the answer has dropped to 37 and is not what I intended at design time ;-0((

Luckily, there is a way out of this possible situation arising in the future.

There is a syntax for us to use, to allow us to specify which parameter we are supplying, and so order of input for the parameters does

not then matter at all.

Study line 39 in the following image :-

Yes, the syntax used is to take the defined parameter in the function (here $my_HighList) and then replace the ' $ ' dollar symbol with a dash, or

minus sign - so it becomes ' -my_HighList ' followed by the correct data item, in this case $my_HighListP.

You can work out the 'low' versions of the syntax for yourselves.

I suggest that it be 'good practise' to always declare the correct parameter and its data input, and NEVER rely on a

default order at all. This way we remove possible error scenarios.

Moving on ..........................

Supplying Default Values - Parameters :

Sometimes we may wish our function to work even if one or more parameters are not provided.

If this is the case, then we can provide default values within the declaration or function definition.

Here is how the first two Functions look after we have provided some default data lists :-

Lines 1 and 12 are those to study in detail.

We can see that 456 + 7 is the sum of the highest and lowest and so the 'average' is indeed 231.5 as seen above.

Note that we have had to change the lines 25/26 in order to do the testing, which effectively ignores data lines 34/35 and

although the call to function 'average' on lines 37/38 appears to use the list, they are not actually used.

This was just a test to see we had the syntax right !

Let us now explore this a bit further and make changes within the 'average' function as well as the calling code.

We can now add a default to our third 'average' function - this is just a bit different ;-0)

Above we first of all see that default parameter values of empty arrays has been added on line 23.

If there are no input parameters we then just call on functions High and Low without data, and effectively use the

defaults within them, otherwise we pass through the filled arrays for processing.

The test we do above is on line 43/44 where we omit one data list.

We can see in the next image that we can also ignore both of the data inputs and have a VERY simple call line of 43.

And when we do NOT provide both filled lists we get the correct default answer of 231.5 and not 87.

Lets now call the 'average' function in the original way, to see if we still generate an answer of 87.

Checkout the following image for full details :-

Yes, we look GOOD - so now all three functions have default values but also all three will work with supplied

and correct data.

Before we move on lets see how NOT to code the IF condition checking script.

We need to remember we are dealing with Objects and not simply values - work out what is wrong with the

following coded script, and why then then get a zero result :-

Lets move on .......................

System Functions and Supplying Parameters :

It would appear that 'cmdlets' and PS system Functions are similar when it comes to providing input parameters.

So if we cover how to do this with Functions we will be able to transfer our skills to command-lets.

By 'this' we mean providing suitable data as input parameters, or NOT and using the defaults instead.

Since this is the case (similarities) then we can use both cmdlets and functions for exploration.

Let us start with a simple cmdlet, or two :-

Yep! - since we see an ascending order in the console display, then the 'Sort' cmdlet must

be using a default valued parameter.

The default seems to be an ascending sort on the main 'Name' field / column.

Let us now try and input some of our own 'stuff' - lets try adding a Property, check this :-

And now we can try this exploratory script - study the details in full :-

Yes, we have a list with version descending all right ;-0)

Lets now try another and different property :-

If we now add a pipe to 'select' or Select-Object, then the default lets all show in the results :-

We can however, soon change this by adding some parameters of our own - or should I say parameter values :-

In the above image we have changed the display order, so our line 3 of the command is doing something right !

Before we can do any more interesting stuff in display etc., we need to know just what objects we are dealing

with, and what their properties may be.

Here is a way to find out :-

[ .. Get-Command | Get-Member (gm) is our friend .. ]

Oh! - there is a bunch more properties we can use ;-)

Lets give it a try :-

Yes, they appear to be present and some values are there as well - Public, Azure ......

Lets see the same code but un-highlighted and with the long line split - check below :-

Okay then guys, that was done with cmdlets so how about we try a Function - see below to select one :-

Yes, we can see that 'Get-Printer' is a Function and not a cmdlet. Lets try that for some fun exploration.

Check this out :-

Now the smart thing to do is first consult the PS Help system to find out details of this function.

Here is what I did :-

Well !? - the Description calls this a cmdlet - strange as this differs from the PS system listing.

I think the help text is wrong and that we have a function - lets run with that.

Moving on a pace :-

The syntax details shown above suggest we can use and supply a 'ComputerName' parameter value.

Lets give that a go :-

And further reducing the results with a filter - try this below :-

We need to try some alternative syntax for the filtering - see the following details :-

================================================================================================================

And although the above works we can clean it up as follows :-

============================================================================

Yes, this seems fine, and probably just what we expected.

The use of Parameters, their value, and leaving some to be defaults, feels pretty good and quite normal

by now - nothing like a few good code experiments to learn a few things for ourselves !

Lets go to the next sub-section to learn some other stuff - see you there ................

PHH - 5th. December 2015.


Why use 'pipelining' with Functions

PHH - 4th. November 2015.


Some of my useful / interesting Functions

Let us carry out an interesting experiment.

Let us write a function using the command way of doing things, and then another Function

in the script writing .NET way of doing things.

The point hopefully, is that we need to keep in mind BEFORE we rush off and program scripts

and our own functions, that there may already be ways of doing what we require - or at least

easier ways based on the command line and cmdlets and piping etc..

Starting simply we have the following :-

Yes, the command-let 'Get-Verb' gives us a nice and convenient list.

If we examine part way down this list we see other Group names :- :-

So using a pipe we can easily change and improve this as seen below :-

That's better, we are now down to the unique Group names even if we have other data values we may wish to discard.

*** be aware *** the property we are after is 'Group' and not 'Name'.

Below, see what happens to the output if we try to use 'Name' :-

In fact case let us continue with 'Group' and improve our pipe command line as follows :-

So if this script works for us, then we can make it into a Function.

Here is my first attempt :-

Whoops ! - misspelling above of 'VerbGroiups' for 'VerbGroups' - will correct this .........

The function seems to work but I would like to improve it slightly.

Now lets do a trial with the newer improved syntax :-

Okay, it still works, but still needs a tweak I feel - try the following with lines 11 and 12

changing to these shown below :-

Great ! - lets keep our 'command based' function as it is above.

Now we need to move on to doing things the .NET way and with some interesting script lines.

Making a list of unique 'Verb' Group names / types :

This below is NOT a recommended way, just the way I first did it when I came to PowerShell. These

days I would do it as in the function above.

If nothing else the following image shows how we can program script lines using a whole bunch of

standard coding techniques - check these details carefully :-

[ .. CARE - this assumes the list to be in order of Group - it should probably be forced to be, initially .. ]

Well, it seems to work for the way data is presented currently from the 'Get-Verb' cmdlet. However,

the script should force the sorting of the long list to be this way before processing with a Foreach

code structure.

You may have you own code approach which stops multiple entries of a single 'Group'. Add these

if you have, and so wish to test out on your PC.

Here below is a tidied up version, but it still relies on the Group property being in order :-

[ .. we will remove this constriction further below .. ]

Okay, we still have a reasonably good result - BUT - we need to remove the need for the original

list of items to be in any preconceived order - or special order.

Lets add some lines and script detail to handle a random order of items - check these details below :-

Looks fine to me, so let us move on a few steps or two ..............

Finding all the Verbs for a Specified 'Group' name :

Let us remind ourselves of what is displayed when we run the command 'Get-Verb'.

Part of what we have to view on screen is shown below - the boundaries of one group to another :-

========================================================================

My 'quest' for the next Function we create is to find all the verbs in the group 'Common', or indeed

any of the seven different groups.

The function is to accept a parameter (input value) of a specified 'group' name as a string, and then find all

the verbs associated with this input value - from the list provided by 'Get-Verb'.

We will need to do a test to see that when we input a string which is NOT a group name, we get a zero

result and empty list etc..

Study this next image VERY carefully :-

So according to our above image result, there are 34 entries in the list for 'Common'.

Here is some of my test script code - it should make sense to you as it stands :-

A good so far, but what about a 'super' function which does all of the entries in the original list ?

A bit like the following command, except that we would also have the lists of verbs for each, not just a number / total :-

============================================

=========================================================================================================

Finding all the 'PowerShell' in-built Functions :

PHH - 3rd. & 26th. November 2015.


Reversing a String

Lets look at a nice way to reverse a string of characters - reverse their order in the string, that is.

Below we will look at a recursive function, just to prove that PowerShell will support recursion.

It is also a smart, clean and tidy way to do the task - BUT - be forewarned, it is NOT an efficient way

to do the reversing if we have long strings. The performance is poor from the timing tests I have carried out.

Trial testing - at 'Twice Reversed' :

Hey guys ! - if we can reverse a string then we ought to be able to reverse it twice and get back

exactly what we started with ;-0))

Lets change our script lines and give this a go - study carefully the following details :-

Well, it does seem to work a-okay ;-)

But shall we also try changing line 22 to see how many braces (brackets) we can remove before

we break our code, or at least the operation of it ?

Lets try the following :-

Yes, line 22 above has only one set of braces remaining, and we get our expected, or target result.

Lets go even further and remove all braces :-

No, the above script code seems to take the second function (name) call as a parameter, and

that is NOT what we intended to happen.

It seems that situations like these are where .NET guys will get caught out - we are used to much

tighter syntax and compiler checking etc.. This is too easy to get wrong in my book, so be warned.

PHH - 5th. November 2015.


Ed Wilson - nice sample

==========================================================

PHH - 16th. November 2015.


Creating 'Advanced' functions

To put it quite simply, 'Advanced Functions' are just standard functions we can design and make, but

with a few extra bits to make them behave in the same ways as the PS 'cmdlets'.

I have said at a few places in these eNotes that it is a good policy for us to try and do our own thing

totally in-line with what Microsoft does with PS and also those experienced guys out there.

So probably many of our functions need to be 'Advanced' functions - we will see as we go along with

this topic, and this sub-section. They incorporate advanced PS features to make them behave like

'cmdlets'.

Let us now make, and then examine, a basic template for an 'Advanced Function'. Check out below :-

[ .. to get us going we are using some starting examples from Ed Wilson, then we will branch out .. ]

[ .. we can have one, or many different 'Write-Verbose' statement lines in our function it would seem .. ]

If we study the above basic template for an advanced function we see some of these 'new parts' we talked about.

First the [cmdletbinding] attribute needs to be present - see line 4 - and this single addition adds some useful extra

capabilities to the function.

We are talking about some additional parameter checking and some easy ways to use 'Write-Verbose' which is

a PS cmdlet.

If we experiment with this basic template, and try to comment the 'Param()' as show below, we get some interesting

on-screen error messages - this is before we try to run the interpreter 'engine'.

Study the following details :-

========================================================================================================

As soon as we add a ' # ' symbol / character at the start of line 5, we get two red wavy lines for errors - see above.

Below, in the next two images we see the detail of these errors - study the details :-

==============================================================================

And also :-

==============================================================================================================================

It appears as though we MUST have Param() with the included attribute.

Try experimenting for yourself - to see what is and isn't necessary.

We also need to try providing and using some parameters rather than having an empty list as seen above.

Moving on .................

Here are some big improvements or additions :

Although I am following Ed Wilson in his chapter 7, I have cut out quite a small detail to arrive at the next

image detail - which is shown below.

I suggest you study my augmented sample - his originally, but with a few of my additions. Note how the

verbose feature helps in testing and checking runtime stuff, if we use the '-verbose' parameter "switch".

The above image shows script code which is clean and easy to follow - and understand.

And the above also does parameter checking as well - see below, from an earlier test :-

Ed Wilson says that what we have done so far in our more Advanced Function saves us needing

to type a lot of our own code each time we make a new function.

He also suggests that we get into adding and using the '-WhatIf' switch parameter as well.

Adding suitable support for the parameter switch called " -WhatIf " :

Here is our growing example with some extras added according to Ed Wilson's advice :-

In the above image line 3 is where the extra facility to handle '-WhatIf' comes from.

Line 20 shown above is how to apply (or call) the switches for both "WhatIf" and "Verbose".

Using ' -Confirm' in our Functions :

The "SupportsShouldProcess" attribute also enables the ' -Confirm ' switch, which is rather handy I feel.

Checkout the running of our growing Advanced Function, with the Confirm switch being used in script code :-

[ .. line 20 is where it is called .. ]

Then after pressing YES we see the following :-

And after YES again we get this :-

And then a final YES gives us this shown below :-

And when we use File Explorer we see the results of the change of system state :-

================================================================================================

PHH - 8th. & 9th. December 2015.


Making and maintaining 'Libraries'

PHH - 5th. December 2015.


Finding .NET Framework versions

http://blogs.technet.com/b/heyscriptingguy/archive/2013/11/02/powertip-find-if-computer-has-net-framework-4-5.aspx

PHH - 1st February 2016.


Appendix 'G' - gotchas ...

For .NET guys like me it is easy to slip into using the wrong operator !?

See below what I tried first in a new function being created - I got no errors of any sort - BUT -

plenty of wrong answers.

=====================================================

This next image shows what I was after, and should have used to start with :-

========================================================

PHH - 5th. November 2015.


Appendix 'H' - using the 'Help' in PS5

PowerShell 5 has lots of built-in help for us to tap into and use.

Although at first glance, and the first few times we use it seriously, it seems dull and uninteresting, it does

actually have a wealth of good information its knowledge base - which is at out finger tips.

The Help files are written in such a ways as to be available to console guys as well as GUI guys.

===============================================================================

Okay guys - the 'Help' command is our friend - it will do a lot for us, and right from our fingertips while using

the PowerShell console, or another software tool.

It even tells us about itself - check this out :-

Okay then, lets run the 'Help' cmdlet to see what it says :-

Before we move on, to use the 'Help' command in the last child-section from here (where we will look at 'select' )

let us go to the next child section and see an in-depth approach to gaining useful information from the Help system.

Good PS users, and experts (call them 'power users' if you will), will certainly be able to get the most from Help it

appears to me!

See you there .............................

PHH - 9th. November 2015.


Get-Help - an 'in-depth' review

Lets start at the very beginning and use 'Get-Command' - we see the following part way through

the LONG list of results :-

And with a bit of filtering we can produce the following in the results pane :-

I assume that 'help' and 'Get-Help' are pretty much the same thing, even though the former is not

an alias but a function.

We are not going to look at 'Save-Help' in these eNotes, so that basically leaves us needing to know how to

do only two things - these are using 'Update-Help' and 'Get-Help'.

We can start with the first of these, lets do an update - check below :-

It would appear that a working Internet connection is required for this to happen.

And here is another snap-shot of the process - I can't capture the green progress bar - there is too much

fast motion ;-0)

And when the process of updating is complete we see this on our screen :-

Once we have current help details we can then start to use them for serious work.

Let us see if we can find out something about using help itself - check this out :-

I am afraid we do need to read a good chunk of the next blue screen detail :-

And finally this as well :-

So let us now follow up the suggestion in the Remarks section just above - lets get some examples :-

And example 4 seems useful too :-

========================================================================================================================

==========================================================================================================

PHH - 7th. December 2015.


S/A utility

In studying and following Ed Wison's eBook I came across an interesting example.

Below is it having first been personalised by myself :-

The utilty is named 'fsutil' - which would appear to mean 'File System Utility'.

If it is written about by Ed Wilson as a 'utility' it sounds like an application - so why don't we

go looking for it with the help of the Start screen ............

Press the Windows key and then type directly 'fsutil' without the single quotes - check this :-

==================================================================

Having chosen the 'location' I then saw the folder where it resided :-

================================================================================================

Or look at it this way - see below :-

========================================================================================

The way to find out the help information is to use the utility itself - the same approach which

can be used for many stand alone applets and utilities.

See how to get the supported commands for this utility :-

So in the above image, if typing 'fsutil' gives us the next level of information detail, then why don't

we try to go yet another level, and type :- " fsutil file " to see what we get, or what happens :-

Great ! - yes, folks it works. We now get the options for the command 'file'.

Note that we can see that which Ed Wilson used - that of 'createnew' - so why not try the same

trick for even more help - check below :-

And once again this works just fine ;-)

This now explains clearly enough what Ed used in his sample.

*** WARNING *** Just be VERY careful as to which other '.exe' file you may try in this way.

If you don't know what they do then be most cautious. Not all give help at level zero '0' !

=====================================================================================================

PHH - 19th. November 2015.


'Select'

https://technet.microsoft.com/en-us/library/ee176955.aspx

Okay folks, lets grab a console window and give the following a go - here is what we start with :-

And here is what we get when the short command line is run :-

I will leave it to you to read, view, and possible take in some information / knowledge from the above images.

The bit that stood out to me was seen in the 'REMARKS' section - see below :-

I am keen to give this a try, so lets go :-

Lets see what example comes up as the first one :-

A good 'catch' !? :

My immediate preference is example '5' which is seen below :-

It seems to me to provide an easy way of doing what I have been struggling over in script stuff I have

been trying out for other parts of the eNotes.

Let me show you what I have done, and why I like the '-unique' parameter. Check this out below :-

*** note *** the character at the extreme RHS is not a pipe but the cursor !!

And here is the result of the command being run :-

Very nice indeed.

No need for me to script 'foreach' loops and the likes ;-0)

PHH - 9th. November 2015.


Appendix ' I ' - getting the most from the ISE

The 'ISE' or "Integrated Scripting Environment" tool is a software GUI desktop application, specially designed

by Microsoft for guys to create and run 'scripts' and 'script' files.

Don't reach for the bog standard 'Console' app and window, until you have checked out the ISE tool first.

Personally, I like the ISE very much - its nice, clear and clean, and NOT too fussy at all.

An example of the ISE in use for a VERY simple script, or set of commands, is seen below :-

In the following child sub-sections we will discover and explorer some of the common and

most useful features, for a guy getting started.

No doubt some can use the ISE in a very much more complex and complicated way, just as

Visual Studio may be used simply or by experts ;-0)

Lets go and see how to launch the tool.

See you in the first child section, next ....................

PHH - 31st. October 2015.


Launching the ISE

On my desktop development PC platform I have both the ISE and the Console app pinned to

my 'TaskBar' - I like using the 'TaskBar' for development work.

When I right click on the TaskBar icon for 'Windows PowerShell' I get the following on screen :-

Notice in the above image that we can (by default) run both the console and the ISE apps.

And as well as that choice we also can run them as 'Administrator'.

Jones & Hicks in their eBook recommend we always run in Administrator mode, probably as

most of us do in Visual Studio as wee.

In the above screen choice I usually choose "Run ISE as Administrator".

However, before we move on, lets see below what a right click on the other 'TaskBar' icon does for us :-

Once again we can launch in Admin mode as long as we first right click the app item in the menu

and then select 'Properties'.

In order to get the apps on the 'TaskBar' go to the Start screen by pressing or clicking the Windows key/icon.

Then simply type 'powershell' to bring up these listed options :-

=====================================================================

And you may get this as well ........ :-

Right click the option you require and you will get a context menu as see in the next image :-

From here you can pin/unpin the apps - I always keep mine pinned.

Here is what my screen TaskBar area looks like :-

In the above screen capture I have the two icons almost at the end of all TaskBar entries - which is on

the third row of my TB entries.

Because I have the full intention of using PowerShell a lot more in the future, I will move the icons by drag

and drop, within the TB area - see below :-

Here, above, I have placed the PS icons first of all the rest in my TaskBar.

Note the TaskViewer is shown at the start of the TB and on the front of each and every row.

I suggest that you look into Windows 10 and how to set-up and use the TaskBar.

Time to move on ..................

PHH - 31st. October 2015.


Basic use of the ISE

Okay guys - we have all used IDE's of one description or another. from Chris's VIDE perhaps, to the flagship

application from Microsoft of 'Visual Studio'.

[ Chris Pygas's VIDE - Vulcan Integrated Development Environment ]

Now then, do NOT panic, as the complexity of 'ISE' [ .. Integrated Scripting Environment .. ] is absolutely nothing

at all as complex as Visual Studio.

In fact ISE is rather refreshingly simple or straightforward ;-0)

We shall love using it and getting meaningful results.

Here is a very simple example of ISE in action - notice below the two text panes :-

Notice above that we have a console type 'command' window as well as a scripting 'Tab' pane.

the 'Tabb' is where we enter and edit our script text.

The two panes can be either vertically arranged or horizontally arranged - and we can even maximise the scripting one

as seen in the next image :-

Here below is the stacked vertically arrangement - note that because the main window is squeezed, the

icon bar is reduced and the extras put into a drop list - which is shown open in the following image :-

In a later sub-section we will examine and explore some of the extra features available from the

menu and top icon bar.

*** Basically *** The application is for entering commands and testing them, making commands into a

script, and then running the scripts to test them, as well as saving them to disk files. Script files

(secondary file names of ',PS') can be run from a command or within other scripts.

We should be able to do just about anything we wish in Windows 10 and MS environment, from PowerShell scripts.

Lets move on ................

PHH - 31st. October 2015.


Entering and saving 'Scripts'

PHH - 31st. October 2015.


Running previously saved 'Scripts'

When we create a new PowerShell 'tab' we get the chance to name it, or have a default name

provided for us if we somehow miss out on the chance.

In the following image we have renamed our opening (launch) tab as "MyPauseSamplePS1.ps1".

Be careful, I think the '1' in 'ps1' comes from the version number of an underlying PowerShell 'engine'

and has nothing to do with the '5' of PowerShell version 5.

Check out the following in detail :-

The above image shows a 5 line script.

We can run the script directly from the menu/icon bar - using the green right pointing arrow - see below :-

===============================

So after pressing 'F5' we get the results of the running of the script in the command / console window.

Check out the details of the next image, taken after the script has run :-

Above we see script in the top pane and results in the lower pane.

With the script still intact within the top pane we can clear the lower console pane with 'cls' the old DOS command

and it is seen typed above, but before the enter key has been pressed.

Here is 'cls' [clear screen] in use - check below :-

If we get things wrong and try and open the same script file a second, or subsequent time, we see a warning

message box like that seen below :-

And as with all IDE's 'ISE' has a GUI and click way to do the same - see below for the alternative :-

===============================================

PHH - 31st. October 2015.


Other IDE features to aid our work

============================================================================

PHH - 31st. October 2015.


Appendix ' L' - Logic / Boolean

PHH - 6th. December 2015.


Appendix 'M' - BCD - 'Modify'

Auto Boot - sequence and adding our own entries :

http://windows.microsoft.com/en-gb/windows/what-happened-boot-ini-file#1TC=windows-7

http://windows.microsoft.com/en-gb/windows/what-happened-boot-ini-file#1TC=windows-7

https://social.technet.microsoft.com/search/en-US?query=bcdedit%20download

http://pcsupport.about.com/od/fixtheproblem/ht/rebuild-bcd-store-windows.htm

This one seems most up to date ? - possibly ! :-

https://msdn.microsoft.com/en-us/library/windows/hardware/ff542202(v=vs.85).aspx

http://www.boyans.net/

PHH - 12th. November 2015.


Appendix 'N' - Notepad, general use and launch

PHH - 2nd. November 2015.


Appendix 'P' - what are 'Providers'

Okay then folks, 'Providers' in PowerShell is all about accessing external information.

By using 'Providers' we have a consistent way of doing this.

In .NET guys parlance we would say we have a common interface between PowerShell and the

actual external information itself.

Ed Wilson tells us that these 'Providers' are actually .NET programs which give us the common

interface, and in so doing hide all the 'ugly details' and / or complex stuff.

It should therefore be of no surprise to us that different sources of information are access in a similar

manner, and by using a common set of 'Cmdlets'.

"Get-Children" is one such command-let, and an important one too.

Apparently, according to Ed., we can take good advantage of 'Providers'.

*** Remember this ***

Providers expose information contained in different data stores by using a 'drive-and-file-system' analogy.

The only difference is the specific name associated with each drive.

Lets take a step forward ..............

What are the drives we can use with our 'Providers' work / exploration ?

Here is a way to find out :-

That looks just fine ;-)

But it may be easier on the eye if we sort it as shown below :-

So at least the Registry drives come together, and the 'FileSystem' ones don't confuse the rest etc..

We shall see these drives used in the child sub-sections from here - in this appendix.

PHH - 29th. November 2015.


Alias Provider

Finding the 'Providers' we have available :

Ed warns us of this :-

===============================================================================================================

Okay then guys what can I find on my PC ? - check out below :-

And as Ed Wilson said we are missing a couple - so see what he has shown us in his eBook :-

========================================================================================

Moving on to some other explorations and experiments .............

Trying our the 'Alias Provider' :

In the following image we will see some appropriate cmdlets being used - and the short hand script is

also shown on the RHS (right hand side).

Check the details over carefully :-

Creating Our Own Alias :

This is the quick and easy way, apparently there are some things/properties not set, but hey!

this is easy man ;-0) Check below :-

And now we need proof that our new Alias entry has 'stuck' or been registered - try this out :-

PHH - 29th. November 2015.


Certificate Provider

In this sub-section we will try to follow through the example from Ed Wilson's eBook - it is

in chapter 3 on understanding 'Providers'.

I am tried to fill-out some of the work on this, with fuller explanations and some extra alternative syntax.

Finding Certificates which have Expired or are dated in the past :

A good piece of advice from Ed Wilson :-

=======================================================================================================================

PHH - 29th. November 2015.


Registry Provider

Ed Wilson has this to say in his excellent eBook (I strongly suggest you purchase a copy) :-

.........................

"Beginning with Windows PowerShell 2.0, the inclusion of remoting makes it possible to make remote registry

changes as easily as changing the local registry.

In Windows PowerShell 3.0, the registry provider was further improved with the introduction of transactions.

In Windows PowerShell 4.0 and Windows PowerShell 5.0, there have been no major increases in functionality. "

.........................

And goes on to say this :-

"You can use the registry provider to access the registry in the same manner that the filesystem provider permits

access to a local disk drive.

The same cmdlets used to access the file system of New-Item, Get-ChildItem, Set-Item, Remove-Item, and the rest,

also work with the registry. "

*** WARNING *** to both you and myself ;-0)

The registry is a rather important layer of our PC's operating system so we had better take care, and NOT do as

I do normally and run off and do my own extra exploration and experimentation.

Tread VERY carefully !!!

So lets try out some of the standard stuff that Ed Wilson recommends we do.

Firstly, lets look at the range of 'drives' that are available to us - there are two default, or standard

ones for the Registry - check below :-

In the Provider column in the above table we locate 'Registry' and then look back to the Name column.

We see 'HKLM' and 'HKCU' - lets do a web search and see what 'HKEY' stands for :-

http://searchwindowsserver.techtarget.com/definition/Handle-to-Registry-Key-HKEY

==================================================================================================================================

So guys, it does NOT mean 'Hot-Key' ;-0)

"Handle to Registry Key" and this is some type of an Alias.

Lets move on a pace or two ..............

Below we will change the 'drive' onto which we are logged :-

[ .. note that I was last using one to explore Certificates .. ]

Okay then folks, we are suitably 'pointing' at the drive for 'HKLM'.

Here is how we check our current location - see below :-

Seems easy enough, as well as being similar to all other Provider approaches.

Lets now see what children we have to hand - what items are within the logged drive location.

*** WARNING - Information ***

I have done the next few steps being logged into drive 'HKCR' and not 'HKLM'. We will see how

to make this new (third) drive later in this sub-section.

In the following image note that we have three versions of the command and aliases :-

Yes, if you try this you will get a HUGE amount of data / results - see the 'thumb' in the vertical scroll bar on the RHS,

this gives some idea of the length of the displayed list.

Lets try an interesting and 'Object' type of new syntax to find the number of list items, or the length of the list :-

Yes, we have almost eight thousand (8,000) entries - the output of a 'Get-ChildItem' cmdlet is and object, and

this list object has a 'Length' property.

Here shown below, is the top of the listed output :-

We appear to have only two property columns.

Lets now output this to a 'GridView' and see if we can filter something useful :-

[ .. be aware that this takes a lot of time for the 'GridView' to be loaded with the data - and general

performance is poor and sluggish. To all intents and purposes it looks as if we get a 'lock-up' .. ]

Here below (and eventually) is the GridView fully loaded with data :-

=============================================================================================================

When we have the GridView open and filled with data we can then more easily set a criterion and a filter condition.

The RHS scroll bar 'thumb' shows that some display data reduction has taken place :-

Lets now change our filter text string to 'object' and see the now large Thumb at the RHS.

To me it seems so though we have a filter on a filter condition - I am not quite sure what the 'criteria' input allows us to do.

I will experiment a little further - meanwhile check these results :-

Oh! - I see, we have to select the multiple properties if we wish for something fancier ;-0)

Below I have tried out a more complex criterion - or applied two criteria ? perhaps.

And yes, above we have only six matches to our filter and criteria.

This GridView could prove to be VERY useful for real managerial tasks I feel - so give it a good try out.

Maybe you ought to try with a data set a little smaller than this current huge set.

Find out what the other drives have to offer - those of HKCU and HKLM, as opposed to 'HKCR'.

Moving on .........................

Seeing Item Details - Retrieving Registry Values :

Ed Wilson says :-

"To view the values stored in a registry key, use either the 'Get-Item' or the 'Get-ItemProperty' cmdlet.

Using the 'Get-Item' cmdlet reveals that there is one property (named default). "

Be very much aware that in the next parts of this sub-section we need to be pointed at the suitable drive

in order to get the correct responses and returned data.

Lets start with default drive 'HKLM' - the local machine drive. Later we will make a new drive of 'HKCR' for

use and testing.

Log on to drive 'HKLM' using the correct syntax as seen below :-

Now then folks lets try this command :-

And in fact the following command also produces the same results (whether the syntax is correct or not).

Study this carefully :-

So what is the significance of " . \ " and " .\. " or " . \ .ps1 "?

We do need to know exactly what we are including in our commands.

Getting to grips with the path notation for navigating through the tree nodes, or folders etc..

Seeing All Items in the Drive (location) :

PHH - 29th. & 30th. November 2015.


Creating a New Drive

Okay then guys, lets look at what I have in my O/S as far as alias and mapped drives are

concerned - Provider drives that is - or even 'PSDrive's !

Check this out carefully :-

Above you will see that there are three existing drives, the two default ones and another named 'HKCR'.

I have made this extra drive following Ed Wilson's directions in chapter 3 of his excellent eBook.

Let me try and remove / delete this added drive so that we can go through the creation process to

demonstrate how to make a new drive.

First lets remove it having first made sure it is not in use - if it is in use (logged into) the

following is what we see in the ISE shell :-

So lets change the 'Location' in the following way :-

And just to check lets do this again :-

==========================================================================

==========================================

So the default drive mappings in the PowerShell provider drive list are for the two above 'Folders'

of "HKEY_Current_User" and "HKEY_Local_Machine".

We are making the mapped drive for "HKEY_Classes_Root", as directed by Ed' chapter notes.

However, we should also be able to make mapped drives for "HKEY_Users" and "HKEY_Current_Config".

One step at a time however so lets check out some nodes and folder names in the Registry :-

==============================================================================================

And now we can do as Ed Wilson suggests - see below for the use of ' .\.ps1 ' :-

PHH - 30th. November 2015.


Path, Folder, File, Node - syntax and symbols

We started off this small sub-section by trying to find out and explain what the following meant :-

=====================================================

And when we reduce this even further we are trying to figure out what the following actual is :-

================================

Since we know by now that the command-let 'Get-Item' returns a data collection if used at the right

place - depending on the current 'folder' in the PSDrive selected.

Then we are trying to determine what " .\.ps1 " means.

Lets start at a recognised place, very familiar to us :-

We often find ourselves at the above location when using ISE and the console.

However, if we do the following :-

We see we are at the root of drive C: as seen below :-

Lets do a simple trial test from the first of these locations - checkout below :-

And an alternative way using an alias is :-

So quite simply a double point ' .. ' means go back two levels of folder (node) if the current one

counts as 'one'.

The consequence of the above statement is that a single point ' . ' means the current node or folder.

In the old days we used to call Folders 'Directories' hence the alias 'dir'.

'cd' means change directory, 'md' means make directory ...........

Here is a better (more interesting) example of the same thing/stuff as above :-

If ..\ takes us up a level of folder / node / directory, the .\ keeps us in the one we are at (or in).

This leaves us wondering from " .\.ps1 " what the extra " .ps1 " means.

Well guys here is a clue - this is what I would normally type :-

I am used to thinking (over MANY years) that " *.* " ( *.* ) means 'everything dot everything !

As in the format 'primaryfilename'.'secondaryfilename' - like "myfile.txt".

PHH - 30th. November 2015.


Transactions

PHH - 30th. November 2015.


'FileSystem' Provider

PHH - 29th. November 2015.


Environment Provider

PHH - 29th. November 2015.


Function Provider

PHH - 29th. November 2015.


Variable Provider

PHH - 29th. November 2015.


WSMan Provider

PHH - 29th. November 2015.


SQL Server

*** CARE *** there seems to be an issue with trying to 'Set-Location' the first time within a PS console / GUI screen.

Even if we remember to add the final (closing) colon character we get errors - see below :-

However, we can 'force' the issue by simply running the cmdlet 'Invoke-Sqlcmd' as seen in the next image :-

And as you can see we have a console screen prompt of the type we are after.

I am not sure what is happening to make it like this !? ;-0((

However, the good news is that we can at least get what we are after by running the 'Invoke-Sqlcmd' command-let.

The next time we wish to use SQL stuff we seem to have no issues - see below :-

It may have nothing to do with this - BUT - I did re-set my default 'Windows 10' links of files with apps yesterday.

====================================================================================

Please note that it was a little more work to find and start using this Provider. For some reason it seemed to be

missing from literature on standard Providers.

However, now that I have found it I have it working very well, as the content of Chapter 13 shows you.

Version 2016 :

https://msdn.microsoft.com/en-us/library/cc281947.aspx?f=255&MSPPError=-2147217396

Version 2014 :

https://msdn.microsoft.com/en-us/library/cc281947(v=sql.120).aspx

Here is some detail from the version 2014 :-

==================================================================================================================

And to use the newly found SQL provider we can do this shown below :-

Notice that it is the 'Set-Location' cmdlet which does what we are after.

Once we have changed Provider we can see what is available using 'dir' or a similar command ('Get-Children') :-

If you have managed to get this far on your system, then try out some of the following :-

And now this :-

Get back to the standard SQL prompt and then try a few SQL queries :-

[ .. the only thing below you will need to change is the name of your Server instance .. ]

So why does this stuff seem hard to get to know about / or find ?

It would appear that it is simply because the Provider is relatively new or recent. There is information and

documentation on the web - BUT - it is missing in published eBooks you will come across out there at the moment.

Here are the results of my book searches - just for interests sake :-

Searching the eBook texts available to me :

I have the four eBooks open in my PDF Reader / Viewer :-

[.. the four texts are those documented in the Introduction of these eNotes .. ]

Now when I try and do a search for 'Invoke-Sqlcmd' in each of the eVolumes we get the following results :-

==========================================================================================================

Above image shows no finds in the "Pocket Reference from Lee Holmes".

And now we search the good eBook from Ed Wilson :-

===========================================================================================================

And very surprisingly Ed's fine text has no mention of 'Invoke-Sqlcmd' !?

So what of Lee Holmes's "CookBook" ?

Check this out too :-

=================================================================================================================================

Wow! - still no hits or matches ;-0((

Lets now try Jones and Hicks - second edition :-

=================================================================================================================================

Well, as you can see we do get a 'hit', but the total content in the eBook is limited to this and a couple more hits, which

is - VERY limited for our purposes.

Now then, if we search Lee Holmes's "CookBook" for some older syntax stuff based on 'Invoke-SqlCommand' we

do get something, but I have by-passed this in my work in Chapter 13.

It would appear that the older 'sqlps' module (with its two 'snap-ins') no longer needs to be loaded - and in fact should not be if we are

using SQL Server version 2014 and 2016.

More about this change will become apparent as we do our exploring and experimentation.

Time to move on ....................

Good Luck with your SQL Server work ;-0))

PHH - 31st. December 2015.


Appendix 'R' - additional 'Resources'

http://www.techrepublic.com/blog/10-things/10-powershell-commands-every-windows-admin-should-know/

=========================================================================================

PHH - 11th. November 2015.


Appendix 'S' - system 'Set' variables

There are variables already set up in PowerShell for our use. Think of these as system

type variables - PowerShell being the 'system'.

Here is on such variable in use below - check it out :-

PHH - 7th. November 2015.


Appendix 'U' - USB devices installed

http://www.techrepublic.com/blog/10-things/10-cool-things-you-can-do-with-windows-powershell/

PHH - 11th. November 2015.


Appendix 'V' - Verbs of the 'Command' line

Appendix 'V' - Verbs of the 'cmdlet' name

Remember that the structure or anatomy of the complex PowerShell command is a shown below.

We first saw this image in 'What is a Command?' at the start of Chapter 0 - check it out :-

=====================================================================================

In the above example the command is 'Get-EventLog' - we call this a 'command let' or 'cmdlet' for short.

So the name of the 'cmdlet' is 'Get-EventLog', and this in itself has a simple internal structure.

The name is said to be made up as 'Verb' then 'Noun' - or if you will and 'action' and a 'thing' (or object).

So in this example 'Get' is the verb, and 'Eventlog' the noun or thing.

Knowing this then suggests a few questions to us developer guys :-

How many 'cmdlets' are there, and how many different verbs are there? Which verbs have the largest sets,

or groups?

Well, we should be able to use some of our developing skills with 'PowerShell' to answer these questions.

Let us first start with a simple enough script, one which will give us all of the Commands in version 5 of PowerShell.

Checkout the following image details :-

And the result of running the script is a VERY long list of Command items - the first few are above, and

the last few are shown in the image below :-

If we examine the last two images we see verbs such as Add, .... Disable, .....Write.

And if we look at a short middle list section we see a few more like those in the next image :-

Above we have Resize, Resolve and Restart .......

So lots of verbs - more on this in a minute.

First lets write a simple script to find out for us the total number of Command / 'cmdlet' names.

To start with lets put all the Command items into a single new variable, check this out :-

=======================================================

And running this simple script we get the following :-

Well, above we have a variable named '$myCommands' and by displaying it we get the full list as we saw before.

This intellisense screen clip capture may interest you :-

And after selection of 'Length' then this captured image as well - see below :-

Now let us find out how many items are in this variable after it is filled - see below for an amended script :-

By running the amended script we see the following in the results console pane :-

However, if we 'Save the script from the File menu in the ISE window, we do not get the script being echoed

to the results pane, just a line of the path for the saved script - check this below :-

Oh! - I almost forget to focus on the result ;-0) Yes, we have 2202 different command lets / 'cmdlet's.

Now let us move on a few steps ............... What about the 'Verbs' ?

Finding and Showing the 'Verbs' :

Well this part is also quick and easy, as we will use PS5 at its best, what its good for, running a 'cmdlet'.

The 'cmdlet' we require is called 'Get-Verb' - remember, verb-noun or action-thing !

Study the next image :-

The above images are two ends of the list sorted on the 'Verb' property - in reverse order.

However we can sort on the 'Group' property as an alternative - see the following results output :-

And if we wish to see the 'Verbs' for the 'Data' noun we have the following - check these out below :-

And after a manual, physical count I end up with a total of 24.

So why don't we do a spot of what we developers do well, some programming - check this out below :-

Well, it does get '24' as a total like our manual count ;-0)

Lets now tidy the script so that we are on our way to using 'Foreach' and a Function to count a specified 'Group'.

Looks like next we require a Function to provide a list of unique (Verb) 'Group' names.

Check this out for a good start .......... :-

PHH - 3rd. November 2015.


Appendix 'W' - file 'association' and 'hidden' changes

http://www.thewindowsclub.com/change-file-associations-windows

Set or Change File Associations & Extensions in Windows 10 :

Each file in your Windows operating system has an extension in its filename eg. .txt, .doc, etc. These extensions are used to identify the program, with which, windows can open this file. You can set or change these file associations in your Windows. In Windows XP you had this setting to change file type associations in Folder Options. In Windows 10, Windows 8, Windows 7 and Windows Vista you don’t see it there, though.

To set File Associations in Windows 8 / 7, Open Control Panel > Control Panel Home > Default Programs > Set Associations. Select a file type in the list and click Change Program.

You will be displayed a list of Programs along with a Description and the Current Default. You can click on the Change program to set or change the current defaults.

Alternatively, you can also right-click the file whose association you want to change > Properties > General tab > Type Of File > Change > Choose a program from the list or recommended or other programs or else click Browse to select one.

PHH - 12th. November 2015.


Appendix 'X' - running EXE files

http://social.technet.microsoft.com/wiki/contents/articles/7703.powershell-running-executables.aspx

How to Auto-start a Set of Programs after System boots up? :

This is however very easy - to autostart programs after system reboot in Windows 10.

To get started, at first turn on Show hidden files, folders and drives.

Open your Control Panel and click on Folder Options.

After that, switch to View tab and enable Show hidden files, folders and drives.

Then, navigate to the following place;

C:\Users\<USERNAME>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

(By default, AppData folder is hidden. That is why you have to show hidden folders to do rest of the steps.)

After going to that place, right click on empty area and select New >> Shortcut.

Then add the shortcut of any program in the empty box

PHH - 10th. November 2015.


Appendix 'Z' - making and using a 'VM'

 Top Previous

PHH - 2nd. January 2016.