Questions About PowerShell Basics That You Were Too Shy To Ask

Developers who are already familiar with application languages will be baffled by different aspects of PowerShell to the beginner to programming. Laerte recalls his initial struggles with PowerShell and answers those questions he wished he'd found quick answers to.

  1. Does PowerShell Support Object-oriented Programming (OOP)?
  2. Is PowerShell’s Execution Policy a security layer?
  3. Can I bypass the Execution Policy Setting?
  4. Can I use cmd (dos batch file) commands in PowerShell?
  5. I saw, in a script, a variable defined as $script:myvariable. What does $script mean?
  6. What are the symbols $_ and $_. ?
  7. If Everything in PowerShell is an object, how can I know all the properties, methods, whatever… all these items from an object?
  8. What is Variable Interpolation?
  9. What is the {0} -f that I saw in some string codes?
  10. What are Scriptblocks?
  11. How can I change a name of a property or add a new one in a output of an cmdlet?
  12. What is dot-sourcing?
  13. In PowerShell, I’m told we can navigate within the registry as if it were a file system. How can this be possible?
  14. I was writing a function and, when checking other codes, I saw a CMDLETBINDING word. What is this good for?

Does PowerShell Support Object-oriented Programming (OOP)?

Yes, PowerShell is built on the top of the .NET framework, so it is safe to say that it supports Object-oriented Programming. A good definition of PowerShell is:

“Windows PowerShell is the new standard Windows command-line shell. Windows PowerShell includes a runtime engine, data providers, core commands (known as cmdlets), a new scripting language, and an interactive prompt. Windows PowerShell is completely object-oriented and processes cmdlets, script files (.ps1), and executable files.” Developing with Windows PowerShell

Before PowerShell 5.0, this was not entirely true. It would be more accurate to use a phrase that my fellow MVP Keith Hill used: “PowerShell is more of an OOP consumer language.”

One of the most exciting and powerful features that were introduced into PowerShell 5.0 was the support for building .NET classes. In the previous versions, the simplest way to create custom objects in PowerShell was by using the [PSCUSTOMOBJECT] or new-object and build a .NET class in C# and, with the add-type cmdlet, import it to PowerShell.

For instance:

Before PowerShell 5.0:

You can implement a constructor, methods, whatever else you want; the entire class definition. Indeed, it was good news for PowerShell developers, but the real unspoken question when developers ask if a language is OOP supported is “Can I use PowerShell to write a full ERP system?

Actually, you can, but you would not want to. PowerShell is intended to simplify and automate administrative tasks on Windows-based systems. Of course, it supports, by legacy, programming languages concepts, but it is not its basic purpose. You can write, for instance, a full CRM system in C++ or even in PowerShell, but in my humble opinion, it is equivalent to using a Ferrari in a farm to carry the milk churns.

You can read more about the implementation of classes in PowerShell 5.0 here:

  1. Hey, Scripting Guy! Blog- Introduction to PowerShell 5 Classes
  2. Implementing a .NET Class in PowerShell v5

Is PowerShell’s Execution Policy a security layer?

No. The execution policy in PowerShell is part of the security strategy but merely prevents potentially malicious scripts being executed by accident and, with the ‘ allsigned policy ensures that scripts cannot be altered without your knowledge. By default, this setting is set to ‘ Restricted , meaning that no PowerShell script file can be run but it will execute PowerShell code within the PowerShell console. If you try to run a .ps1 script from file with execution policy set to restricted, you will face the message:

… but if you copy code from the .ps1 file and paste it into the PowerShell console it will be executed.

Can I bypass the Execution Policy Setting?

Yes. You can execute a PowerShell script file by calling it from a .bat shell-script file: This will bypass the execution policy in the system. Actually there are several ways to bypass the execution policy, but in this example, it is achieved merely by calling PowerShell.exe using the ‘ bypass‘ option in the -ExecutionPolicy parameter.

2399-2016-03-30_8-56-28-bb43228c-a553-46

For more information about execution policies:

  1. TECHNET – Set-ExecutionPolicy

Can I use cmd (dos batch file) commands in PowerShell?

Yes, you can. PowerShell can launch external programs in almost the same way as cmd and it accepts all the cmd commands as legacy.

2399-cmdnew.png

I saw, in a script, a variable defined as $script:myvariable. What does $script mean?

Variables, aliases, functions and drives in PowerShell all work within ‘scopes’. This simply means that they are visible – or available – and changeable (mutable) only in the part of a script that you intend. This prevents values being changed unintentionally. In PowerShell, we can define four types of scope: global , local, private and script

When you include an item (or items) within a scope, by running a script or function, creating a new session or starting a new instance of PowerShell, it will be visible only in the scope within which it was created and in any child scope. This rule does not apply to private scope. In the same way, it can only be accessed or changed in its original scope. If you use the same name for another item in a different scope, the original variable will be hidden under the new item, but will not be overridden or changed.

For instance, if you create a variable inside a function, you cannot access (or change) its value in the script level where the function was called.

Global Scope

The global scope is the scope created when PowerShell starts. Any Item that is created when PowerShell starts or created with $global will be visible in the entire session and in all other scopes, as long it is alive. It is only when your code enters a nested prompt, script, block or function that a child scope is created. You can force a variable to be in global scope by using the $global: prefix to the variable.

Local Scope

The ‘local scope’ is the default scope when you create a variable with no scope defined. Any item that is created within a function is available only within the script of function.

Script Scope

It is available from all scopes within the script, or in any script called within the parent script. While the script is running, you can think as it is the same a Global scope

For instance:

In the next example below, I show how the script and local prefixes work to change values. In this script, I first created a variable called IamScript in the Script scope. Inside the function, I could access the value but I then tried to change the value not specifying its scope, so it created a new variable, locally only to the function with the same name.

If I want to change the value of the variable, I need to specify the scope:

What are the symbols $_ and $_. ?

The $_ variable-name is placeholder. Actually every script language uses placeholders and variables to store data. In this case, we could say that it where the data that comes out from a pipeline is held. In PowerShell everything is an object, and when you refer to a $ _ , you are using the entire object that is coming from the pipeline: Of course, you can also also choose a property, method or any item from this object using $_.Property syntax .

In PowerShell 3.0, an alias to $_ was introduced, called $ PSItem

$_ actually works like $this except that it means ‘this object’. Just as you can use it in a pipeline, you can use it in a Switch statement or any other processing structure.

Which would give…

If Everything in PowerShell is an object, how can I know all the properties, methods, whatever… all these items from an object?

Use the cmdlet Get-Member

2399-2016-04-04_6-30-32-b3e011b3-ffe0-43

What is Variable Interpolation?

When you add a variable to a double-quoted string, PowerShell replaces the variable name by its value. This feature is called variable interpolation.

2399-2016-04-04_6-57-59-7b1feb8e-1ae1-4b

You can hit a problem with variable interpolation if you include an object property (or even a result of a method) in the string. The standard notation of (dot property ) or ( . myproperty) does not work as expected . For this problem, PowerShell has a subexpression operator $(). This operator first evaluates and run what is inside the brackets to resolve it into a simple value before passing it to the string for interpolation.

So here is a PowerShell script that will hit problems

2399-2016-04-04_7-10-00-96d0355c-b621-43

So you need to use the $() syntax. In this case, PowerShell will evaluate the $ SQLBrowser.status first, and then will interpolate the rest of the string.

Another very important point is that the variable interpolation only happens in double-quoted strings so if you will don’t need interpolation, then use a single-quoted string instead.

What is the {0} -f that I saw in some string codes?

This is string formatting using the PowerShell format operator. In PowerShell, you do not need to use “+” operator to concatenate strings. Actually is more in-tune with PowerShell syntax if you use interpolation or the -f (from format)

It is simple. You add the placeholder {N} and then type a command-separated list of values in order to be replaced. {0} represents the first value in the command-separated list, {1} the second and so on.

You can, of course, do this more simply with variable interpolation, but the Format operator is the one to use if you need to format numbers, currencies, scientific notations, and dates. You can specify precision, separators and any or all fields within a date. You can also use it to align text.

What are Scriptblocks?

Scriptblocks are one of most Powerful concept of PowerShell. By definition, is a collection of statements or expressions between “{” and “}” that can be used as a single unit. It can be stored in a variable, can be passed to function and can be executed remotely by the operator “&”

Syntax :

{<statement list>}

Like functions, a scriptblock can include parameters :

And script blocks can include the DynamicParam, Begin, Process, and End keywords.

The Basics

Adding Parameters

Running Remotely

How can I change a name of a property or add a new one in a output of an cmdlet ?

You may use custom tables.

Custom tables are a especial type of formatting output that uses the constructor @{} with the elements Expression and Name inside it , separated by semi-colon, to customize the output :

Expression is the data you want to display. Note that it is a scriptblock, so you can only display a property or write an entire script inside it.

Name is the header to appear in the top of the column. But how it can be used? Let’s check some examples:

If you run a Get-Process you will have the output :

Well, the header names are a bit hard to understand. I am a Brazilian and want to just show the Handles and ProcessName Columns as they are, but I would like the ‘ ProcessName title translated to Portuguese :

Now I want to add the property ComputerName :

As I said before, the Expression is a scriptblock so I can call a function inside it:

Note : the Expression and Name elements can be shorted to E and N

What is dot-sourcing?

In simple words, it is the way that you can make available in your current scope such items as variables or functions from another script.

As we saw before, scripts or functions have their own scope. So if I start a PowerShell session and want to load items in the current scope and keep them visible in the session, the way you can do it is by dot-sourcing this script.

Let’s create a function called foo that just displays a message in the screen:

Then in the PowerShell host call this function in a standard PowerShell notation (.\NameofTheScript):

2399-1-52bf74bd-0ceb-44e3-b6fe-171c3ebb1

If I try to load the function again as a native cmdlet (just the name of the function) I will get an error because it was visible only when was called and destroyed after that.

2399-1-407d6f0d-34b0-45ac-a3b4-a69d560b1

But if I dot source this function and then try to call as a native cmdlet, it will work. Everything inside that .ps1 file now is available in the current scope.

2399-1-ea2ed633-ebd0-4e1e-b8e2-d77687434

In PowerShell, I’m told we can navigate within the registry as if it were a file system. How can this be possible?

Amazing, huh?

Yes, in PowerShell we have providers. In simple words, they are little .NET programs built in in PowerShell that allow you work with data as a file system.

We can check all the PowerShell providers by using the Get- PSProvider cmdlet :

2399-42091764-fedd-4ebe-9788-d09f3c9afab

In the first column we have the name of the provider, followed by Capabilities – what the provider supports – and then the driver to access this provider.

As I said, you will work with these as file system; so to access the registry provider, just use the CD Drive: notation

Then it is just a matter of changing the “subfolders “to keep navigating within it. ( CD \ Software ..etc)

It is not only the registry, as you can see. You can do the same for variables, certificates, functions, Environment variables, aliases and so on  ..

I was writing a function and, when checking other codes, I saw a CMDLETBINDING word. What is this good for?

It’s simple. You are saying to your function “Hey beautiful, please from now on work as a compiled cmdlet”.

When you define the cmdletbinding attribute in a function, PowerShell binds its parameters the same way as it does the C# compiled cmdlets. This means this function is now an advanced function and it has access to all the features of the compiled cmdlets, as common parameters.

Functions, Advanced Functions are a huge topic. Please refer to my previous article: The PoSh DBA: Grown-Up PowerShell Functions.

That’s it guys. I´ve tried to address some of the questions that I had when I first started out with PowerShell, but if your questions are not in this list, please don’t be shy, email me laertesqldba@outlook.com and I will do my best to help.