How to get started writing a PowerShell script | From idea to action

When you’re given a task or you have a task you want to automate, what approach do you take? What kind of steps do you do? Let’s say you want to copy files from a directory to another.

The first thing I like to do is to see what kind of cmdlets that is available in regards of the task you want to solve. This can be done by running the following command:

With this command you can filter on parameters like name, noun and verb to find the most suitable cmdlet to use. Since we are going to create a script that copies files, we can get all commands containing copy with the examples below. Note, that I might have different modules and cmdlets installed, therefore some cmdlet may be different. From the result below, we will use the cmdlet Copy-Item.

When we have found the proper cmdlet, we need to know how it can help us, by asking for help. This can be done by using the cmdlet Get-Help. This gives you a manual on how the cmdlet works. and there are many different ways you can ask for help, that is often useful when learning about a new cmdlet. See some examples below.

Now that we know a thing or two on how to get help, we can start by testing out the cmdlet in the command line. Lets say you want to take copy of your Documents folder to a Backup folder, we can do this by running the following command.

This command does the trick, but typing this command for each item in a folder manually isn’t very efficient. Now, let’s see how we can do this for each item within a folder now that we have the core command in place.

Looping through folders

To find how we can loop through each item in a folder we can use Get-Help foreach.

The foreach lets us repeat a section of code, in this case repeating the Copy-Itemcmdlet for each item in a specified directory, but first we need to now how to list out all the items in a folder. To find out, we can use the Get-Command again to look for something that lists items in a current directory.

Now that we now how to list items in a directory and we know how to repeat a task for each item in a directory, we can now combine these two cmdlets with the following.

The first example code says for each object in the parentheses, perform the action that’s defined within the curly braces. The Get-ChildItem in the foreachstatement grabs a list of items in the specified path and stores them temporarily in the $itemvariable. Inside the loop the variable $itemis used to refer to the single object returned by this particular iteration of the loop. For each iteration the Copy-Item command is called and the item is moved to the specified destination.

The second example pipes the result from the Get-ChildItem cmdlet to the foreachcommand and for each item copy the result to the specified destination. The $_ variable can be seen as the $itemvariable in the first example, it refers to the single object returned by the particular iteration of the loop. This is one way we can repeat tasks for multiple items.

Adding variables

Furthermore, that we can copy all items in a folder, we can further enhance the script by adding variables. This makes it easier to edit what the parameters in the script, by separating the functionality and values, it’s also a step towards avoiding hard coded values. If you save and run the script below you will be able to copy items specified in the $Pathvariable to the path specified in the $Destination variable. By creating variables you can edit the value without editing the action of the command. Save the file as Copy-Items.ps1 and then run it from the command line and the script will execute the script (if you have the same file and folders) otherwise it will display an error message that the current path doesn't exists. Execute the script by running for instance PS C:\>ScriptsCopy-Items.ps1.

Parameterizing the script

To enhance the script even more we can add parameters to the script, this allows us to specify the value of the variables, which let’s us specify the directory we want to copy and the destination we want to copy, each time we run the script. To execute the script below with parameters, you can do as follow: C:\Scripts>Copy-Item -Path C:\Documents -Destination C:\Backup. It allows us to specify the values of the variables more interactively than in the previous step, and is starting to become a more useful tool.

To further improve the script we can explicit define the data type of the parameters. This helps validating that the input parameter has the correct data format.

Creating a function

Further more, we can create a function out of the script. A PowerShell function is a list of statements that has a name assigned to it, in this case we call it , since we are copying all items in a specified folder. To call a function you need to load the script into memory by using dot source like this . C:\Scripts>Copy-Items.ps1, then you can run the function just like a PowerShell cmdlet, Copy-Items -Path C:\Documents -Destination C:\Backup.

Remember when you’re working with a function you must load it into memory each time you make an adjustment to it, otherwise you can be quite confused when you run the script and nothing different is happening. It can be useful to open a new PowerShell instance with or using the up arrow on the key board to reuse the dot source command, this is quite effective when you get use to it.

Naming convention

When creating function and PowerShell tools, use the same naming convention as the PowerShell cmdlets. This makes it more intuitive and easy to use by keeping it consistent. You don’t need to invent the wheel again. For instance in the script we have created I’ve used the same variable names as the parameters to keep it consistent and intuitive, and easier for other to get started when there is one way to name variables and parameter names.

More, when creating a function use the Verb-Noun naming standard. To get a list of all available verbs in PowerShell, you can use the cmdlet Get-Verb. Use a verb that matches to action of the script and make sure to use descriptive names that explains the functionality of the script. Also use the PowerShell case standard, Pascal case.

In short the reason you want to follow the PowerShell naming convention is that you want to build your tools and functions to be exactly like a PowerShell command.

Creating a cmdlet

Adding [CmdletBindng()] to the script. When PowerShell see this attribute, it treats the command like a cmdlet. A cmdlet has a lot of neat features, one of them is the cmdlet Write-Verbose, this allows you to verify what the script is doing while running, by outputting a descriptive text you can activate when the function runs, by adding the -Verboseparameter, like so Copy-Items -Path C:\Documents -Destination -Verbose. The [CmdletBindng()] also a has other features like Debug, Write-Verbose, ErrorAction and more. In this post we focus on -Verbose .

When you run the function, this will output

A final touch

Now we have a full worthy script that let’s us copy files within a folder to another folder, the last thing we need to do is creating documentation of the script.

If you now run Get-Help Copy-Items, you can get the help information about the cmdlet, this is useful if you have created the script once, and then need to run in a later state, also if others is using the tool.

To wrap up

Now we have create a simple script using simple steps to create a fully working script. I hope you find the steps useful and understandable. I’ve also added a list below with some other tips that came to mind when writing this post. Hope you enjoyed and learned something from it.


  • Don’t start creating a script, the first step is to test and figure out the core command in the console. Then when you’re troubleshooting you only have one problem to relate to, then take baby steps until you have a fully working tool, like we did in this post.
  • Use double quotations when using cmdlets like Write-Verbose, Write-Hostand Write-Output, then you can use variables without have to concatenate.
  • If you us PowerShell ISE you can put your cursor on a cmdlet, and hit F1 and then a new window with the help manual for that cmdlet opens up.
  • Don’t use Write-Hostif you plan to make modifications to the object you write to the console, this cmdlet will only output plain text, while Write-Output keeps the object in place, and you can make modification to the object. The is Write-Hostuseful when writing status updates when scripts are run by using it's parameter -Foregroundcolor where you add colors, for instance; red for errors, green for success, yellow for warning.

Originally published at



Developer | Dynamics 365 | Power Platform | Azure | Personal development | Investments

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Fredrik Engseth

Developer | Dynamics 365 | Power Platform | Azure | Personal development | Investments