PowerShell Command Prompt Boot Camp
This section will give a brief boot-camp / accelerated crash course to get up to speed on PowerShell quickly. It won't be very in depth, but it should provide enough info you can get by or at least search for more in-depth pages about a certain topic. It also won't teach you how to program scripts or some of the PowerShell best practices or gotchas - it's a basic "get started fast" guide. This overall guide was mainly just about the Command Line in general, but once you know the basics you want to start learning more - start here!
I assume you can complete the CLI Task Test, if not run through Zen's CLI Crash Course first. Most what you may know about the CMD/"DOS" Prompt may also be useful. This will just be a surface-level guide, not a deep-dive. Enough to help point you in the right direction and know what to Google if you get stuck. For the basics see the PowerShell Essentials page.
PowerShell commands (officially called cmdlets) are generally always of the form Verb-Noun or Action-Subject,
and the Noun or Subject will have several Verb/Action related commands, such as Get-Content
,
Set-Content
, Add-Content
, and Clear-Content
to get the contents of a file, write a
file, add to a file, and empty a file.
Get-*
commands are usually always safe to run as they just retrieve some information
Set-*
commands are used to change or to set some value(s)New-*
commands are used to create something new (like a folder or other object)Remove-*
commands delete somethingGet-Verb
to see them all - but people still use non-standard Verbs too.
PowerShell commands/cmdlets always use a single dash - to indicate options/parameters/switches/arguments, such as
-Identity
or -Properties
. Any value comes after, such as: -Identity jsmith
. PowerShell commands/cmdlets and options/parameters are not case
sensitive, but usually displayed using PascalCase so words forced together AreEasierToRead. Cmdlets and Parameters are often
long so use Tab Completion.
PowerShell cmdlets come in various modules: many of which are included with Windows/PowerShell, come with other programs
(like Active Directory or SQL Server), or can be downloaded from the PowerShell Gallery. Load a module with Import-Module
(though often just using a cmdlet
will auto-load the module in PowerShell 3.0+) and install a module with Install-Module
. See all the modules
installed on your system with: Get-Module -ListAvailable
→ Sometimes there are prefixes to the Nouns/Subjects to group commands, such as Get-ADUser
,
Set-ADComputer
, Remove-ADGroup
each having an "AD" prefix.
Because PowerShell is very regular and discoverable the 3 most useful commands to initially learn are listed here:
Get-Help
(alias = help
) to display the Help Text for any command, cmdlet, or just about
anything. Using -full
will usually give you detailed help and examples, such as:
help get-content -full
(you can skip right the examples with -Examples
, as
in: help get-content -examples
). See the Essentials page for
more details.
You can also get help on various internal aspects of PowerShell, they all start with about_ such as
help about_variables
or try help about_
to see a list of all internal help files.
Get-Command
(alias = gcm
) to search for and find various commands, cmdlets, functions, etc.
Similar to CMD's where.exe
but with much more flexibility and fine-grained control. You can use -CommandType
to search for only certain commands or functions, or -Module
to limit searching to a certain Module as in
gcm -module ActiveDirectory
But just filtering on the Name is simplest: see all the "Get-" commands on your system try gcm get-*
or
if you want to see all Verbs/Actions you can perform on Services try: gcm *-Service
or to see any
command pertaining to "computers" try gcm *computer*
Get-Member
(alias = gm
) to get all the Properties and Methods/Functions that
are returned from a command/cmdlet or belonging to a Type or Variable. Because PowerShell is "all
objects" every Object can have hidden Properties (values) or Methods/Functions (actions you perform). Most of
these are all .NET based since PowerShell relies on the .NET Framework (or .NET Core).
A command like Get-Date
returns the current Date and Time, but the value returned isn't just a text
string of characters, you can see the Type and all the various Properties and methods with:
Get-Date | gm
which will show that its Type is System.DateTime, and it has over 50 Properties
and Methods that contain just the Seconds, Hours, Days, or Months and let you convert the DateTime to different
formats or Add days, hours, months, etc to get a new DateTime. (we'll see how to access these Properties/Methods
below)
Relatedly, the 3 most useful concepts in PowerShell are: Variables, Objects, and the Pipeline. We'll cover these in greater detail in the next sections.
Since everything is an Object (which will be discussed in the next section): a PowerShell command can return a lot of data, you can use Variables to store this data and access it again later; or create your own variables to avoid having to re-type the same thing over and over. There are some built-in and automatic variables. Think of a variable as a bucket with a label: the label is the name of the variable and the bucket holds the value. You retrieve the value by referencing the bucket by the name on the label. If you change the contents of the bucket: anywhere after it is referenced by name will use the new value.
$Username
or $SomeLocation
$Username = "jsmith"
or $SomeLocation = "c:\temp\folder"
$today = Get-Date
(the right hand side
is evaluated first and then assigned to the variable on the left)$SomeLocation
) such as:
$ListOfFiles = dir $SomeLocation
(now $ListOfFiles
will contain a list of all
the files located in $SomeLocation
)$null
which represents nothing or an empty
variable, you can clear a variable by setting it to $null
such as:
$Username = $null
Often a cmdlet will return more than one value (such as many files in a directory, many AD Users, many Processes, etc) in
those cases the results will be an Array which is List or Collection of items. An Array can also be assigned to a
variable in exactly the same way. However the variable name (eg. $ListOfFiles
) will point to
the Array, not one particular item in the array. To select just one item from the Array you use an Index number -
which starts at 0, in [square brackets] after the Array variable name.
$ListOfFiles
has has 10 files, then the first is $ListOfFiles[0]
and the last (the 10th) is $ListOfFiles[9]
It's also worth briefly noting that variables have a Type in addition to a Name and a Value - the Type
is the sort of Value the bucket holds. Common types are String (a sequence of characters, "such as a sentence in
quotes"), Int (for Integer, a number without a decimal place: 0, 1, -6, 689, but not 1.5 or 3.14),
Float (for floating point, a number with a decimal place: 0.0002, -0.5, 1.11178, 2.0, 3.14), Boolean (a
value that is only either $True
or $False
- two special variables
that represent True or False), DateTime (a Date and/or Time value, such as returned by
Get-Date
), and any other valid .NET type. Think of the Type as the Colour of the variable bucket: there's a
name of a variable but also a colour denoting if it's holding text, numbers, dates, etc.
"6"
is a very short 1-character String. Try
adding them to together in PowerShell, note the order makes a difference: (you can just type these at the PS C:\>
prompt.5 + "6" = 11
(because "6" is converted to the number 6), but "6" + 5 = "65"
(because now 5
gets converted to the string "5" and concatenated/appended to "6" creating a 2-character String)A final type of Variable worth mention is the Environment Variable. These are set either per-machine or per-user by the system but
contain useful information, such as the name of the computer or currently logged in user, the location of the Windows folder, and more.
In the CMD Command Prompt you access them with %
as in %USERNAME%
but in PowerShell
you access them like any other variable using $
but in the ENV:
virtual drive.
So the current logged in user is $ENV:USERNAME
, and they work in Strings too, such as "My computer is $ENV:COMPUTERNAME"
.
If PowerShell is all about Objects, what's an Object? An Object is "Structured Data + Methods to work with that Data". Think of an Object as a Large Bucket with several smaller Buckets inside plus the Tools to "do things with those buckets". The smaller buckets are Properties (the Data - basically a bunch of related variables) and the Tools are Methods (or Functions, that can do things with the Properties/variables). Objects are structured because every Object also has a Type and all Objects of the same Type follow the same structure, like a Template (having the same Properties and Methods available as the Template they were created from).
Object variables have their name on the Large Bucket that you can pick (like $UserObject
) but
the Property and Method names are set by the template Type for that sort of Object.
You can reference the Properties and Methods with "dot notation" - by using the Object's variable name, a dot .,
and the
Property or Method. Eg: $Object.Property
or $Object.Method()
→ Properties are just variables and hold values, sometimes you can set them, other times you can only
get them (if they are read-only).
→ Methods are functions that perform actions, possibly returning a value; you need to use
(parentheses) to call a function, and pass any parameters inside the parentheses like: $Object.Method(parameter1, parameter2)
Get-ADUser
, such as:
$UserObject = Get-ADUser -Identity jsmith
might be:$UserObject.Surname
might return "Smith"$UserObject.GivenName
might return "Jane"Get-Date
, such as $Today = Get-Date
might be:$Today.ToString()
would return the date and time you ran Get-Date such as "2/24/2020
10:20:42 PM"$Today.ToString("yyyy-MM-dd")
would tell the ToString() function to return only the
date in YYYY-MM-DD format, such as "2020-02-24"$Today.AddDays(4)
would return the date exactly 4 days from now on Feb 28.$ListOfFiles
is an Array of 10 items/files then $ListOfFiles.Length
would return 10$ListOfFiles[9]
. The
Length is a count of how many items there are, starting at 1: it could be 0 (for no items), or 1, 2, 3, 10, or hundreds
of items. But the Index runs from [0] to [Length -1]Often you need to access Properties, Methods, or even just evaluate a PowerShell expression, variable or command
within another command or context. You can use sub-expressions to do this by enclosing the
command/variable/expression
in brackets like: (Some-Command)
and then you can access Properties/Methods, like: (Some-Command).OneProperty
Get-Date
to a variable such as $Today
(see above),
or enclose it in brackets: (Get-Date).ToString("yyyy-MM-dd")
(Get-ADUser -Identity jsmith).Surname
"Today's date is $($Today = Get-Date; $Today) and tomorrow is $($Today.AddDays(1))."
PS C:\> $Today = Get-Date
PS C:\> # With "double quotes" it will resolve the $Today variable:
PS C:\> "It is $Today"
It is 02/24/2020 12:13:17
PS C:\> # With 'single quotes' it will print exactly as written:
PS C:\> 'It is $Today'
It is $Today
The PowerShell Pipeline is what allows you to link commands (or Variables) together to process, filter, or otherwise
do something with the values. The Pipeline is denoted by the vertical bar or Pipe character: |, which separates
commands/cmdlets, expressions or variables. Each section of the Pipeline feeds the next: the Output of one command
becomes the Input of the next. Almost all PowerShell commands/cmdlets and many scripts output Objects that can be
accepted as input via the Pipeline by other commands/cmdlets/scripts - the Pipeline passes Objects. You can think of it as
an unnamed Array of Objects where the current Object is represented by the special variable: $_
though often you don't need to reference individual elements of the Pipeline since by default commands will work on
all elements of the Pipeline. Usually a command changes or filters (narrows) the Output as compared to the Input. You
can have as many 'sections' of the Pipeline as you want, but unwieldy commands can be shortened by using Variables. Be
careful mixing non-PowerShell (regular Windows Console CMD commands) and the PowerShell Pipeline: non-PowerShell commands
output plain text, not objects!
Some common simple commands that work with the Pipeline are: Sort-Object
, Measure-Object
,
Group-Object
(usually just referenced by their aliases: Sort
, Measure
, and
Group
). By default the final result of the Pipeline is displayed on the screen, so you'll see the results.
dir c:\windows | Measure
dir c:\windows | Sort Length
dir c:\windows | Group Extension | Sort Name
Other common Pipeline commands involve displaying information: Format-List
, Format-Table
(usually
just fl
and ft
), Out-String
or Out-GridView
-- these almost always come
at the end of the Pipeline:
dir c:\windows | fl
(you can still add | more
after to show a page at a time)dir c:\windows | sort Length | Out-GridView
help
with them. For example, the last one is literally "directory of C:\Windows, sorted by file Length, whose
output goes into a GridView (a kind of pop-up list of data window)"
Saving/exporting (or reading/importing) data to/from files using Pipeline data is possible too: Set-Content
,
Add-Content
, Out-File
, Export-Csv
, Get-Content
, Import-Csv
,
ConvertTo-Html
, and ConvertFrom-Json
-- usually you want the raw data to be exported, so
don't place these after Format-List
or Format-Table
dir c:\windows | Set-Content c:\temp\output.txt
OR
dir c:\windows | Export-Csv -NoType c:\temp\output.csv
$Results = Import-Csv c:\temp\output.csv
Remember, use Get-Help
(maybe with -Full
or -Examples
)
to look up what these commands do, what the Required or Optional parameters do (such as what -NoType
does for Export-Csv
-- remember you only need to specify enough to uniquely
identify parameters).
Two of the most important, and common, Pipeline commands are Where-Object
(or just Where
, or
even just a single question mark ? as an alias) which filters which Objects to pass along the Pipeline
(that is: only pass along Objects which match some search/filter criteria). And Select-Object
(or just
Select
) which filters which Properties of Objects are passed along the Pipeline (that is: only pass
along Properties that are listed, no others).
→ Where
filters Objects, Select
filters Properties (of Objects)
Combined with other commands you can filter/choose which Objects or Properties to keep and which to discard, depending on
what you want to do.
Where
uses either the older/classic script-block format (which still allows more complex filters) or the newer
(PS 3.0+) native format. In either case you choose aspects (usually Properties) of Objects and those Objects that match are
passed along and those that don't are discarded.
-and
, -or
, -not
(or the exclamation ! character), -eq
(equals), -ne
(not equals), -gt
(greater than), -ge
(greater than or equal to), -lt
(less
than), -le
(less than or equal to), -like
, -notlike
, -contains
, -in
, and
several others. These work like in algebra and return $True
or $False
.5 -gt 3
is $True
(because 5 is
greater than 3).Where
format: dir c:\windows | Where LastWriteTime -lt "2019/01/01" | Measure
(to see how
many old files there are)Where
format: dir c:\windows | Where {$_.LastWriteTime -lt "2019/01/01"} | Measure
(note
the Where
filter is in {curly braces} and needs $_
to reference Objects
in the Pipeline)Select
uses names of Properties (including partial matches using wildcards, where * = any characters)
to filter what results get passed along. You can list one or more Properties, or Expand a Property if it contains multiple
values or SubProperties; or choose just the First or Last number of items, or only return Unique values from a
collection/array of Objects. Generally all the Objects are passed along, just not all their Properties - use
Where
to filter whole Objects.
dir C:\Windows | select Name, Fullname, LastWriteTime
dir C:\Windows\notepad.exe | select Name, *Time*
Format-List
or
fl
) rather than Table (aka Format-Table
or ft
), so seeing one item is easier than
all.| select *
you can see them
all.dir C:\Windows\notepad.exe | select *
dir C:\Windows\notepad.exe | select VersionInfo
and
dir C:\Windows\notepad.exe | select -expand VersionInfo
dir C:\Windows\notepad.exe | select -expand VersionInfo | select *
-First
or -Last
, such as:
dir c:\windows | select -last 3
Select
(especially useful with
Export-Csv
if you see a Type or something else unhelpful, but it displays correctly at the Console because
it's multi-valued). Calculated Properties require a Hashtable with Name and Expression Keys (we
haven't covered Hashtables, they're similar to Arrays but are made up of Key/Value pairs). An example would
be:dir c:\windows | select Name, @{ Name = 'LastWriteDay'; Expression = {$_.LastWriteTime.ToString("yyyy-MM-dd")} }, LastWriteTime
Select
's functions can be done directly with ft
/ fl
as a
convenience, this avoids needing to do: dir | select Name, LastWriteTime | fl
, you can just do:
dir | ft Name, LastWriteTime
PowerShell has many advanced control structures as well, but because this document is about the basic Command Line usage and
not Programming/Scripting we'll just mention a few here. You will need to learn these (especially foreach
and
if
) to create scripts or solve more advanced problems with PowerShell. For now, focus on being comfortable with
PowerShell and the Command Line in general.
The Pipeline cmdlet: use the Foreach-Object
(or the aliases: foreach
or even just the
percent sign
% by itself) to do something to everything in an Array/Collection in the Pipeline, where $_
represents the current Item/Object being processed, like with Where
, for example:
dir | foreach { write "Here is a file: $($_.Name)" }
. Note: the default action of the Pipeline is to pass all
objects to the next command, so you only need foreach
if you want to accomplish something specific with each
item.
The confusingly named PowerShell statement: foreach
which is very similar to Foreach-Object
(especially since alias for one is the same as the other - PowerShell figures out which) but the foreach
doesn't use the Pipeline but names each item it works on (the $file
variable in the example
below) instead of using $_
.
Which foreach
method you use doesn't matter a lot, one will make more sense in some situations and the other in
other situations. Use whichever makes the most sense at the time - ie. are you working with data in the Pipeline? Within
.PS1 scripts the foreach
statement is often used to do multiple things to each item in the array. Have a look
at
the example below - they both produce the same output.
PS C:\> $AllFiles = dir c:\windows
PS C:\> # With the Foreach-Object cmdlet you process via the pipeline (input and output):
PS C:\> $AllFiles | foreach { write "Here is a file: $($_.Name)" }
Here is a file: addins
Here is a file: ADFS
Here is a file: etc, etc
PS C:\> # With the foreach statement you declare a variable to work with the Array, no Pipeline:
PS C:\> foreach ($file in $AllFiles) { write "Here is a file: $($file.Name)" }
Here is a file: addins
Here is a file: ADFS
Here is a file: etc, etc
The conditional IF
/ELSE
statement, which uses Conditionals like Where
does, is
used for branching and making logical decisions (often called If ... Then ... statements). You can decide to do
something IF a certain condition is true or ELSE do another thing.
A script that is just a collection of commands saves you from having to type them over and over, a script
that uses
variables is more flexible and easier to maintain and update, a script that uses loops (such as above) can do the same thing
to all
Objects in an Array without repeating lines - but a script that can make decisions can be very powerful (eg. Install
X, if successful do Y, else do Z).
An example of a simple if
is below:
PS C:\> $value = 35
PS C:\> # Use IF to decide what to print:
PS C:\> if ($value -lt 20) { write "$value is a small number" } else { write "$value is a big number" }
25 is a big number
Here is an example of a small script which has several lines within a script block, you can copy and paste it into a
# Tells you if a number is larger or smaller than 20
$MyArray = 5, 10, 15, 20, 25, 30, 35, 40
write "Starting..."
foreach ($Number in $MyArray) {
# Several lines inside the foreach {script-block}
if ($Number -lt 20) {
write "$Number is smaller than 20"
} elseif ($Number -eq 20) {
# several lines inside this if/elseif script-block
write "-=-=-=-=-=-=-"
write "$Number IS Twenty!!"
write "-=-=-=-=-=-=-"
} else {
write "$Number is larger than 20"
}
}
write "All done."
Note that the above example also included ELSEIF
which lets you stack several conditions into one
IF
statement (IF this, ELSEIF that, ELSEIF another ELSE final option).
Other control structures include For
loops, Do
While
or Until
loops,
Switch
statements, and Functions. Most of these are beyond the scope of this document, and probably not anything you'll need
right away.
But custom functions allow you to encapsulate common commands into a subroutine you can re-use - and keep your code
tidy.
Functions are blocks of code that you can use and re-use within your code. You can define Functions on the command line or,
more commonly,
within scripts (.PS1
files) -- they are like mini scripts within scripts. You can define and
pass parameters
to functions, and they can return values (but they don't have to). Any value that is output within a Function is returned
when the Function
exits. This allows you to assign the output of a function to a variable, like: $var = My-Function
.
In many languages you need an explicit return
keyword, but it's
optional in PowerShell - where any
output in the Pipeline
is returned. This often causes headaches for people coming from other scripting languages, so it's worth pointing it out (in
case
you are used to
another programming/scripting language like JavaScript, Python, C/Java, etc).
To create a Function just use the function
keyword, the name of the function, and put any
optional parameters you
want in (brackets). Then put your code in {curly braces} after - called a script-block. It's best to follow the standard
Noun-Verb
naming convention. There's a lot more you can do with functions, including supporting the help
command or
validating parameters with
Advanced Functions which can also allow you
to accept
Pipeline input. Functions don't have to be long, they can be short and just save you from typing the same code over and
over.
PS C:\> # You can enter functions on one line in the Console, or across several lines in a script.
PS C:\> # See the current date:
PS C:\> Get-Date
Tuesday, June 9, 2020 10:26:07 PM
PS C:\> # Define a function with no parameters:
PS C:\> function Get-Tomorrow { (Get-Date).AddDays(1) }
PS C:\> # Test it:
PS C:\> Get-Tomorrow
Wednesday, June 10, 2020 10:26:20 PM
PS C:\> # Define a function with a parameter and then assign the results to a variable:
PS C:\> function Get-FutureDate ($Days) { (Get-Date).AddDays($Days) }
PS C:\> $NextWeek = Get-FutureDate -Days 7
PS C:\> $NextWeek
Tuesday, June 16, 2020 10:26:45 PM
Write "Some text."
will output via the Pipeline (and by default display on the
screen), whereas Write-Host "Some text."
will not output via the Pipeline - it displays directly on the
Console screen.write
and
write-host
Write-Host
verses Write
.return
statement it's not needed as anything output to the Pipeline (such as by
write
or from a command) is returned by a function.My-Function $Param1 "value 2" -Switch3
do not do this: My-Function ($Param1, "value 2", -Switch3) -
that will create an Array!-parameter
name with a function or cmdlet if you match the
order of the arguments
Mentioning Write-Host
and Write
above it's worth expanding briefly on these, and also how to
accept user input. Normally a script
takes its input from a file (like a .CSV file), from another command, or parameters on the command line. But sometimes being
able to ask the user for
input can often be beneficial (and simpler) too, that's where Read-Host
comes in.
Write
is an alias for Write-Output
(the alias echo
also works), and as mentioned
above sends whatever it prints get sent
to the Pipeline and displayed by the Shell on the Console. It's the implied final item in a Pipeline, even if you
don't specify it.dir | sort Length
and dir | sort Length | Write-Output
are semantically the same.write
in a Function the output goes to the Pipeline and is returned by the Function (instead of
being displayed on the screen)Write-Host
sends whatever it prints directly to the Console window, bypassing the Pipeline. If you
use it in a Function it will just
display on the screen, it isn't placed in the Pipeline or returned.-ForegroundColor
and -BackgroundColor
options, so
you can do:write-host -fore red -back green "It's Christmas time!"
Read-Host
you can! You can
even specify a prompt/question;
the input is returned as a String, but PowerShell can convert to a number. You could ask for someone's name using:$Name = Read-Host -Promp "Please enter your name"
and PowerShell will wait for the operator to type
something and press Enter, placing
whatever is typed in $Name
.Here's two versions of the same Function, one using Write-Host
and one using Write
to illustrate:
PS C:\> # With Write-Host note that the message displays when the Function is called:
PS C:\> Function Add-Nums ($a, $b) { write-host "Adding: $a and $b."; $a + $b }
PS C:\> $c = Add-Nums 3 10
Adding: 3 and 10.
PS C:\> write "The answer is $c!"
The answer is 13!
PS C:\> # With Write instead, where the message is returned into $c
PS C:\> Function Add-Nums ($a, $b) { write "Adding: $a and $b."; $a + $b }
PS C:\> $c = Add-Nums 3 10
PS C:\> write "The answer is $c!"
The answer is Adding: 3 and 10. 13!
It's not that either is right or wrong, they both have their places. However, it's usually more correct to use
Write
and only return
whatever should be returned from within a Function (and only use Write-Host
to display diagnostic information.
A few other helpful things worth mentioning before finishing this PowerShell Boot Camp:
.replace()
and .join()
, but
there's also the -replace
and -join
Operators (which are very
similar but also support Regular Expressions, RegEx). Examples to
try:(dir c:\windows).Name -join "; "
(write "My name is Jane!").replace("Jane", "Sarah")
.Trim()
, .ToUpper()
, .ToLower()
and more, check out:"Any string" | Get-Member
to see all the functions you can use!.\nameOfScript.ps1
with the leading .\
(or use Tab Completion)powershell.exe -Command .\script.ps1
After all that, you can also customize your $PROFILE
- which is a built-in variable that points
to a configuration file that
PowerShell executes whenever it is started. You can see the path and filename by just typing the $PROFILE
or
open it up in an editor
with something like: notepad $PROFILE
. You can place configuration options and small "helper" functions to use
on the command line.
Your $PROFILE
is yours, it's saved in YOUR Windows Profile, so if you use any of the functions
you add in anywhere scripts
they won't be available on any other systems or running as any other users (such as scheduling a script to run under
SYSTEM). You should only place
functions/settings in there that you will use while administering a system from PowerShell, if multiple systems you'll need
to copy it over.
# Some configuration for the built-in PSReadline module:
# Make Up and Down arrows act more like CMD's command history:
Set-PSReadlineOption -HistorySearchCursorMovesToEnd:$true
Set-PSReadLineKeyHandler -Key UpArrow -Function HistorySearchBackward
Set-PSReadLineKeyHandler -Key DownArrow -Function HistorySearchForward
# Some helper functions for the command line:
Function Get-OffsetDate ($Days = -7) {
# Returns the date $Days in the past/future (default = 7 days ago)
# Example: dir | Where LastWriteTime -gt (Get-OffsetDate -5)
(Get-Date).AddDays($Days)
}
Function Format-Date ($Date = (Get-Date)) {
# Returns a date in just "YYYY-MM-DD" format (default = Today)
# Example: $TwoWeekDateStamp = Format-Date (Get-Date).AddDays(14)
(Get-Date $Date).ToString("yyyy-MM-dd")
}
Function Truncate-String ($String, $Length) {
# Truncates/cuts a string to Length by cutting off characters on the RIGHT
# Example: $FirstFiveChars = Truncate-String "0123456789ABCD" 5
if (!$String) {
$null # If no string then return null
} else {
# Return a portion of the String, the lesser of $Length or the String's .Length
$String.substring(0, [System.Math]::Min($Length, $String.Length))
}
}
Function Read-Input ($Prompt, $Default = "") {
# Returns input like Read-Host except just pressing Enter returns a $Default value
# Example: $FileName = Read-Input -Prompt "Enter a file name" -Default "data.csv"
$Input = Read-Host "$Prompt, or accept [$Default]"
if ($Input -eq "") { $Default } else { $Input }
}
Feel free to use any of these, but if you use them in scripts you'll need to copy and paste them into the script before calling them.
Of course this is just scratching the surface of PowerShell, but it should be enough to get you started!