The title “System Administration” covers many different things. According to careers.govt.nz, a systems administrator develops, maintains and administers computer operating systems, database management systems, and security policies and procedures.
System administration includes many steps from planning what is required, deploying, maintaining, and eventually retiring systems. With the development of virtualisation and cloud computing, what used to take weeks to accomplish has reduced to minutes. Prior to virtualisation if a new system was required someone had to decide what hardware to purchase, then have it shipped, installed, configured, and tested. Now someone can ask for a system, and they can have it in five minutes with cloud technologies. However, all these additional systems need to be monitored and maintained.
This is possible due to automation and in particular, scripting. A system administrator is always going to be looking for a way to avoid repeating the same task. If it must be done manually, there is a significant chance it will not be done. The person may be away or they may be busy with something else. There are all sorts of reasons why it may not be done. If it is automated, the system will do it. In addition, when people do a task, there is always a chance that they will make a mistake. A script will only make a mistake if it is coded incorrectly.
Scripting does not create new programs. Scripting calls upon, and ties existing methods (e.g. troubleshooting methodologies) and tools together.
Troubleshooting methodology
Often, computer technicians spend a large percentage of their time troubleshooting the various software and hardware components used in computers, networks and printers. Before you can even begin to troubleshoot a physical problem with a piece of hardware or diagnose an error thrown up by a software program, you need to understand the basics of troubleshooting and some common best practices.
The most elaborate toolkit and expensive diagnostic software can be useless if you do not have a consistent plan for solving problems. Even experienced technicians can sometimes overlook obvious problems or solutions. Troubleshooting can be extremely challenging, but if you follow basic best practices and conventional troubleshooting procedures, you will often be able to determine the specific cause of a problem, as well as possible solutions to the problem.
To some extent, being an effective troubleshooter simply involves having a detailed knowledge of how something is supposed to work and of the sort of things that typically go wrong. However, the more complex a system is, the less likely it is that this sort of information will be at hand, so it is important to develop general troubleshooting skills to approach new and unexpected situations confidently. Troubleshooting is a process of problem-solving. It is important to realise that problems have causes, symptoms and consequences.
Consider:
- A computer system has a fault in the hard disk drive (cause).
- Because the disk drive is faulty, the computer is displaying a 'blue screen' (symptom).
- Because of the fault, the user cannot do any work (consequence).
From a business point of view, resolving the consequences of the problem is more important than solving the original cause. For example, the most effective solution might be to provide the user with another workstation, then get the drive replaced.
It is also important to realise that the cause of a specific problem might be the symptom of a larger problem. This is particularly true if the same problem recurs. For example, you might ask why the disk drive is faulty—is it a one-off error or are there problems in the environment, supply chain and so on?
Problem management
Any organisation that has to deal with more than a few problems every week will have a system in place for problem management. The basis of problem management is the identification, prioritisation and ownership of incidents.
The process of problem management is:
- A user contacts the help desk, perhaps by phone or email. An operator (or technician) is assigned to the incident and a job ticket is generated.
- The user describes the problem to the operator, who may ask clarifying questions. The operator categorises the problem, assesses how urgent it is, and how long it will take to fix.
- The operator may take the user through initial troubleshooting steps. If these do not work, the job may be escalated to deskside support or a senior technician.
- Troubleshooting continues until the problem is resolved. At that point, the user is contacted to confirm that the problem has been fixed. The job ticket is updated with details of the problem and how it was resolved. The ticket is then considered closed.
At each stage, the problem management system can track the ownership of the problem (who is dealing with it) and its status (what has been done). Each of these stages needs to consider and be guided by corporate policies, procedures and impacts before making changes. An enterprise network is, by definition, highly interconnected. Even small changes can have major, unintended impacts, so it is imperative that you follow established change management procedures and know when to seek authority to make a change.
Developing a troubleshooting mindset
Troubleshooting is not just the application of technical knowledge and expertise; the approach you choose to take is equally important.
Be calm: If you are calm, it instills confidence in the customer and will also prevent you from making rash decisions.
Take breaks: Troubleshooting requires a great deal of concentration. After a long period of working on the same task, the mind can become fatigued and concentration is reduced. Consider taking breaks or leaving the problem for a while to refresh your mind.
Challenge assumptions: A problem may be reported that is similar to one that you have experienced before, but you should not assume that the problem is identical. Although the symptoms may be similar, the problem and its solution could be completely different. Always treat each problem as a new challenge. Be prepared to try something different. If you have decided what the problem is, but cannot seem to solve it, it may be that you are incorrect. Be prepared to start again from the beginning with an open mind.
Assess costs and impacts: Remember, you must account for corporate policies and evaluate the impact of a problem. A particular problem might be a stimulating challenge, but if resolving it is not the highest priority in terms of business needs, you need to give up on finding The Answer and use a shortcut to get to a solution. When assessing whether to repair a part, consider the cost of the part and the cost of your time to perform the repair. In many circumstances, replacement is the most effective option.
Know when to give up! You will not always be able to fix the problem yourself. Be prepared to pass the problem on rather than wasting the user's time!
Being able to view and visualise the diagnostic information of computer systems is of particular importance to systems administrators. Luckily, all modern operating systems make this information relatively easy to access.
Here are a couple of easily accessible tools to visualise diagnostic information in Windows.
Instant Search box and Run Command
The Instant Search box on the Start Menu/Start screen will execute programs and configuration options using simple names. You can open any file or program by pressing the Windows key then typing the path to the file. In the case of registered programs and utilities, you simply need to type the program file name or utility name. Alternatively, you can access the Run dialog box using Windows+R or entering 'run' into the search box.
.MSC extensions and the Run line
There are several management consoles that you can access via the Run line via the .MSC extension. For example:
- devmgmt.msc opens the Device Manager console
- diskmgmt.msc opens the Disk Management console
- compmgmt.msc opens the Computer Management console.
Command line tools
Most configurations of Windows can be done via convenient GUI tools, such as the management consoles and Control Panel. In some circumstances, though, it is necessary to use a command prompt to configure or troubleshoot a system. As you learn the commands, you may also find it quicker to use the command shell for actions (such as file management).
Learning commands is also valuable if you have to write scripts to automate Windows.
Command Prompt
You can run any command from the Run dialog box. However, to input a series of commands or to view output from commands, you need to use the command shell (cmd.exe). To open the prompt, type 'cmd' in the Run dialog box or Instant Search box.
You may need to run the command prompt with elevated privileges in order to execute a command. If a command cannot be run, the error message 'The requested operation requires elevation' is displayed.
You cannot continue within the same window. You need to open a new command prompt as administrator. Right-click the command prompt shortcut and select Run as administrator then confirm the UAC prompt. Alternatively, type 'cmd' in the Instant Search box then press Ctrl + Shift + Enter.
PowerShell is a powerful and versatile cross-platform scripting language developed by Microsoft for automating and managing various tasks. It provides administrators, system engineers, and IT professionals with a command-line interface (CLI) that combines the capabilities of traditional command-line shells with the flexibility and extensibility of a scripting language.
At its core, PowerShell is designed to simplify and streamline administrative tasks by providing a unified framework for interacting with different components of the Windows operating system, as well as various software applications and services. It allows users to perform a wide range of operations, such as managing files and directories, configuring system settings, executing complex scripts, and automating repetitive tasks.
One of the key strengths of PowerShell is its emphasis on object-oriented programming and its ability to manipulate and interact with objects in the Windows environment. This object-oriented approach enables users to access and control different aspects of the operating system and applications through a consistent and intuitive syntax.
PowerShell also offers extensive support for command-line operations, scripting, and automation. It provides a vast library of cmdlets (pronounced "command-lets"), which are small, single-purpose commands that can be combined and piped together to perform complex operations. Additionally,
PowerShell allows users to create and execute their own scripts, enabling them to automate routine tasks, customize system configurations, and build powerful solutions tailored to their specific needs.
PowerShell serves as a comprehensive automation and management framework that empowers users to efficiently administer and control Windows systems, saving time and effort while enhancing productivity in diverse IT environments.
There are many resources for learning PowerShell. A person called Ed Wilson used to be “the scripting guy” for Microsoft. He asked his wife, Teresa Wilson (also referred to as “scripting wife”) about her thoughts on learning PowerShell. She wrote a blog on ways to learn PowerShell: https://devblogs.microsoft.com/scripting/weekend-scripter-the-best-ways-to-learn-powershell. It highlights the number of resources that were available in 2015.
Since then there have been many more resources added. It is recommended that you have a look at the following:
- https://learn.microsoft.com/en-us/powershell
- https://learn.microsoft.com/en-us/training/paths/powershells
- http://eddiejackson.net/web_documents/The_Administrator_Crash_Course_Windows_PowerShell%20v2.pdf
Due to the number of resources available, most introductory training sites do little more than give an overview of how to put PowerShell scripts together. This course does the same, partly due to the rapidly changing nature of what PowerShell can do.
Getting started
PowerShell can be run interactively or as a script. To run interactively type as much of “powershell” into the search area as is required to make the command come up and then press enter. At this stage does not matter if use “PowerShell ISE” or “PowerShell”. If you are running Windows 11, Terminal also has PowerShell interface where commands can be entered.
When commands are run interactively, they cannot be reused. It is often useful to check the commands in an interactive environment, but in order to be able to reuse them, the commands must be in a script. There are numerous ways of creating scripts because they are simple text files, but tools like Notepad do not offer as much help as other tools that are designed to help build software. Tools designed to help develop and debug software are called Integrated Development Environments (IDEs). Two popular options are Visual Studio and Visual Studio Code. Visual Studio Code, developed by Microsoft with the Electron Framework, is a free and lightweight yet powerful source code editor. It runs on various platforms, including Windows, macOS, Linux, and Raspberry Pi OS. It offers features like debugging support, syntax highlighting, code completion, snippets, code refactoring, embedded Git, and even has an extension specifically for editing PowerShell code.
For details see this learning resource.
Activity
Install Visual Studio Code and enter the following code and run it.
get-vmhost | export-csv $env:userprofile\desktop\vmhost.txt
This will take a few moments to run. Check your desktop for a new file called vmhost.txt.
Variables in PowerShell are placeholders used to store and manipulate data during script execution. They act as containers that can hold various types of information, such as numbers, strings, arrays, or objects. Variables are declared using the $ symbol followed by a name, and their values can be assigned, modified, and retrieved throughout the script. PowerShell supports dynamic typing, allowing variables to hold different data types based on assignment. They enable flexibility and automation by facilitating the storage and retrieval of data, allowing scripts to perform operations and make decisions based on the stored values.
$MyVariable = 1, 2, 3 $Path = "C:\Windows\System32"
Variables can be used to store the results of commands.
$Processes = Get-Process $Today = (Get-Date).DateTime
When working with bytes PowerShell uses KB, MB, GB, and TB to make computer sizes more readable. 20MB or 20GB or 20KB is much easier when the system is expecting bytes.
$MaximumFileSize = 20MB
There are system variables such as $env:homedrive and $env:homepath that can be used. The $env: tells PowerShell to look for the “environment variable”. In this case, the default home drive and home path for the user will create a way to access the current user’s home folder.
$VMName = "newVM" $VHDPath = "$env:homedrive + $env:homepath + "\" + $VMName + ".vhdx" $VHDPath
Activity
Get the value associated with each of the following environmental variables:
- COMPUTERNAME
- NUMBER_OF_PROCESSORS
- PROCESSOR_ARCHITECTURE
- SystemDrive
- SystemRoot
To get a list of all the environmental variable can use the command:
get-childitem env:*
Activity
Assign the value of the environment variable Number_of_Processors to a variable called NumberOfProcessors. Using the Write-Host command have it generate the complete statement “The number of processors in my system is (number of processors)".
$NumberOfProcessors = $env:Number_Of_Processors write-host “The number of processors in my system is $NumberOfProcessors”)
Operators in PowerShell are symbols or keywords used to perform various operations on data. They enable computations, comparisons, and logical evaluations within scripts. PowerShell supports a wide range of operators, including arithmetic operators, comparison operators, assignment operators, and logical operators. These operators allow for mathematical calculations, comparisons of values, logical evaluations, and control flow in PowerShell scripts. They are fundamental tools that help manipulate data, make decisions, and automate tasks based on certain conditions or criteria.
Arithmetic operators in PowerShell are symbols used to perform mathematical computations. The + operator adds numbers, the - operator subtracts them, the * operator multiplies them, and the / operator divides them. The % operator calculates the remainder of a division. For example, $a = 5 + 3 sets the value of $a to 8, and $b = 10 / 2 sets the value of $b to 5. These operators allow for numerical calculations and are commonly used in PowerShell scripts for mathematical operations.
Comparison operators in PowerShell are used to compare values and determine their relationship. Comparison operators in PowerShell are used to compare values and determine their relationship.
- -gt (greater than)
- -lt (less than)
- -ge (greater than or equal to)
- -eq (equals)
- -le (less than or equal to)
- -ne (not equal to)
These can be used to compare both numerical values and strings. For example:
- “box” -gt “alpha” is true because ‘b’ comes after ‘a’.
- 10 -gt 9 is true because comparing the values but
- ‘10’ -gt ‘9’ is false because “9” as a string is greater than “1” as a string.
When working with strings there are another couple of common operators:
- -like – can use a wildcard so that -like ‘*shell*’ is anything with shell in it
- -notlike – is anything that does not match the “like” criteria
Use the -like comparison when you want to find all the instances that have a particular string. For example, if you want to find all the files that have the filetype “.txt”. The command “get-childitem” will retrieve all the files in the current folder and then the following command will filter the files to find all the .txt files.
Get-childitem | where {$_.Name -like "*.txt"}
In most cases, using the verb “get” in PowerShell will return objects. Get-VM will return a series of objects about the VMs on the system. Any of the properties can be used to filter the objects returned by using a “where” statement. The $_ is a shorthand for “the objects returned by the previous cmdlet”. Try modifying the above command to select a different extension such as “.doc”. For details about operators see: about Operators - PowerShell | Microsoft Learn.
In PowerShell, objects are fundamental elements used to represent and manipulate data. Objects are instances of .NET classes or PowerShell's built-in types, encapsulating both data and behaviour. They provide a structured and hierarchical way to organize and interact with information. PowerShell treats everything as an object, including files, directories, processes, and even simple data types like strings and numbers. Objects have properties that store data and methods that define their behaviour. PowerShell's object-oriented nature allows for powerful data manipulation and automation. It enables accessing and modifying properties, invoking methods, and chaining commands together to perform complex operations on objects. Try running the following command:
get-childitem | format-list
You will see that each file has a lot of information associated with it including:
- Name
- Length
- CreationTime
- LastWriteTime
- LastAccessTime
- plus many other items.
Each file returned is an object with all the properties. This site provides information about the properties associated with files: PowerShell | Microsoft Learn
Try modifying the following command to filter for Size of file ($_.Length) and Files created after or before 1/1/2023:
Get-childitem | where {$_.Name -like "*.txt"}
Using flow control, scripts can change how they run in response to specific conditions. Loops, switches, and if statements allow for data filtering, repeated operations, and selective code execution. Script flexibility, automation, and the capacity to effectively handle a variety of circumstances are all improved with flow control. Conditional We previously looked at using “Where” to identify large files.
$LargeFiles = Get-childitem | Where {$_.Length -gt $MaximumFileSize}
This works well as a filter for results, it doesn’t allow for different actions to be performed based on the condition. To do this we can use an “IF” statement.
if $f.Length -gt $MaximumFileSize { write-host “$f.Name is over $MaximumFileSize” } else { write-host “$f.Name is no larger than $MaximumFileSize” }
An IF statement in PowerShell evaluates a specified condition and executes a block of code based on the result. Here's how it works:
- The condition is evaluated. It can be a comparison, a logical expression, or any valid condition.
- If the condition evaluates to true, the code block within the IFstatement is executed.
- If the condition is false, the code block within the else statement (if provided) is executed instead.
- After executing the appropriate code block, the script continues executing the subsequent statements after the IF statement.
The IF statement allows for the selective execution of code based on conditions, providing the ability to control the flow and behaviour of the script based on specific criteria or situations.
Point to think about: Why was the output for the “else” statement “is no larger than”? What would happen if the file size is the same as $MaximumFileSize? A fuller description of the power of the IF statement together with some system administration applications can be found at: Back to Basics: Conditional Logic with PowerShell If-Else.
More technical details of the IF statement can be found at: about If - PowerShell | Microsoft Learn.
Nested IF statements are hard to read. It is easy to lose track of where the logic is, so if you are wanting to do an action based on whether it is a, b, or c a switch statement is better and easier to read. For example a menu. The user can enter “1”, “2”, “3” or “q”. Any other entry is invalid.
$ans = read-host "Please enter selection (1,2,3, or q)" switch ($ans) { 1 {"1 selected" } 2 {"2 selected" } 3 {"3 selected" } q {"exit"} Default {"Please enter 1, 2, 3, or q"} }
For more details see: Back to Basics: Understanding the PowerShell Switch Statement.
Loops
The following statement collects a list of large files, where the file size is over $MaximumFileSize.
$LargeFiles = Get-childitem | Where {$_.Length -gt $MaximumFileSize}
Using a “Foreach” command, each file that is collected can be processed.
Foreach ($L in $LargeFiles) { $L.Name + “ is “ +_$L.Length }
The other loop option in PowerShell is “DO”. All DO loops get executed at least once and are then rerun depending on whether the WHILE is true or the UNTIL is false.
$i = 1 DO { Write-host ‘$i is ‘ $i $i = $i + 1 } while ($i -le 10) $I = 1 DO { Write-host ‘$i is ‘ $i $i = $i + 1 } UNTIL ($i -gt 10)
It is important to make sure that the UNTIL will eventually become true or the WHILE will become false otherwise will have an infinite loop. There are more options available. The most widely used ones are described at Flow control - PowerShell | Microsoft Learn.
Navigating and viewing files and directories
Windows PowerShell uses the noun 'Location' to refer to the working directory and implements a family of cmdlets (lightweight commands) to examine and manipulate your location.
To determine the path of your current directory location, enter the command:
Get-Location
# Output
C:\Documents and Settings\PowerUser
The Get-Location
command is used with the Set-Location
command. The Set-Location
command allows you to specify your current directory location.
Set-Location -Path C:\Windows
After you enter the command, you will notice that you do not receive any direct feedback about the effect of the command. Most Windows PowerShell commands that perform an action produce little or no output because the output is not always useful. To verify that a successful directory change has occurred when you enter the Set-Location
command, include the -PassThru
parameter when you enter the command:
Set-Location -Path C:\Windows -PassThru
# Output
C:\WINDOWS
The -PassThru
parameter can be used with many Set-
commands in Windows PowerShell to return information about the result in cases in which there is no default output.
You can specify paths relative to your current location in the same way as you would in most UNIX and Windows command shells. In standard notation for relative paths, a period (.
) represents your current folder, and a doubled period (..
) represents the parent directory of your current location.
For example, if you are in the C:\Windows folder, a period (.
) represents C:\Windows
and double periods (..
) represents C:.
You can change from your current location to the root of the C:
drive by typing:
Set-Location -Path .. -PassThru
# Output
C:\
The same technique works on Windows PowerShell drives that are not file system drives, such as HKLM:.
You can set your location to the HKLM\\Software
key in the registry by typing:
Set-Location -Path HKLM:\SOFTWARE -PassThru
# Output
HKLM:\SOFTWARE
You can then change the directory location to the parent directory, which is the root of the Windows PowerShell HKLM: drive, by using a relative path:
Set-Location -Path .. -PassThru
# Output
HKLM:\
You can type Set-Location
or use any of the built-in Windows PowerShell aliases for Set-Location
(cd, chdir, sl). For example:
cd -Path C:\Windows chdir -Path .. -PassThru sl -Path HKLM:\SOFTWARE -PassThru
When changing locations, it is helpful to keep track of where you have been and to be able to return to your previous location. The Push-Location
cmdlet in Windows PowerShell creates an ordered history (a 'stack') of directory paths where you have been, and you can step back through the history of directory paths by using the complementary Pop-Location
cmdlet.
For example, Windows PowerShell typically starts in the user's home directory.
Get-Location
# Output
C:\Documents and Settings\PowerUser
The word stack has a special meaning in many programming settings, including .NET Framework. Like a physical stack of items, the last item you put onto the stack is the first item that you can pull off the stack. Adding an item to a stack is colloquially known as 'pushing' the item onto the stack. Pulling an item off the stack is colloquially known as 'popping' the item off the stack.
To push the current location onto the stack, and then move to the Local Settings folder, type:
Push-Location -Path "Local Settings"
You can then push the Local Settings location onto the stack and move to the Temp folder by typing:
Push-Location -Path Temp
You can verify that you changed directories by entering the Get-Location
command:
Get-Location
# Output
C:\Documents and Settings\PowerUser\Local Settings\Temp
You can then pop back into the most recently visited directory by entering the Pop-Location
command, and verify the change by entering the Get-Location
command:
Pop-Location
Get-Location
# Output
C:\Documents and Settings\me\Local Settings
Just as with the Set-Location
cmdlet, you can include the PassThru parameter when you enter the Pop-Location
cmdlet to display the directory that you entered:
Pop-Location -PassThru
# Output
C:\Documents and Settings\PowerUser
You can also use the Location
cmdlets with network paths. If you have a server named FS01 with a share named Public, you can change your location by typing:
Set-Location \\FS01\Public
or
Push-Location \\FS01\Public
You can use the Push-Location
and Set-Location
commands to change the location to any available drive. For example, if you have a local CD-ROM drive with drive letter D that contains a data CD, you can change the location to the CD drive by entering the Set-Location D
: command.
If the drive is empty, you will get the following error message:
Set-Location D:
# Output
Set-Location : Cannot find path 'D:\' because it does not exist.
When you are using a command-line interface, it is not convenient to use File Explorer to examine the available physical drives. Further, File Explorer would not show you all of the Windows PowerShell drives. (Windows PowerShell provides a set of commands for manipulating Windows PowerShell drives, and we will talk about these after you have watched the video below.)
Working with files and directories
Navigating through Windows PowerShell drives and manipulating the items on them is similar to manipulating files and folders on Windows physical disk drives. This section discusses how to deal with specific file and folder manipulation tasks using PowerShell.
You can get all items directly within a folder by using Get-ChildItem
. Add the optional Force parameter to display hidden or system items. For example, this command displays the direct contents of Windows PowerShell Drive C (which is the same as the Windows physical drive C):
Get-ChildItem -Path C:\ -Force
The command lists only the directly contained items, much like using Cmd.exe's DIR
command or ls
in a UNIX shell. In order to show contained items, you need to specify the -Recurse
parameter as well. (This can take an extremely long time to complete.) To list everything on the C drive:
Get-ChildItem -Path C:\ -Force -Recurse
Get-ChildItem
can filter items with its Path, Filter, Include and Exclude parameters, but those are typically based only on name. You can perform complex filtering based on other properties of items by using Where-Object
.
The following command finds all executables within the Program Files folder that were last modified after 1 October 2005 and which are neither smaller than 1 megabyte nor larger than 10 megabytes:
Get-ChildItem -Path $env:ProgramFiles -Recurse -Include *.exe | Where-Object -FilterScript {($_.LastWriteTime -gt '2005-10-01') -and ($_.Length -ge 1mb) -and ($_.Length -le 10mb)}
Copying files and folders
Copying is done with Copy-Item
. The following command backs up C:\boot.ini
to C:\boot.bak
:
Copy-Item -Path C:\boot.ini -Destination C:\boot.bak
If the destination file already exists, the copy attempt fails. To overwrite a pre-existing destination, use the Force parameter:
Copy-Item -Path C:\boot.ini -Destination C:\boot.bak -Force
This command works even when the destination is 'read-only'.
Folder copying works the same way. This command copies the folder C:\temp\test1
to the new folder C:\temp\DeleteMe
recursively (repeatedly):
Copy-Item C:\temp\test1 -Recurse C:\temp\DeleteMe
You can also copy a selection of items. The following command copies all .txt files contained anywhere in C:\data
to C:\temp\text
:
Copy-Item -Filter *.txt -Path c:\data -Recurse -Destination C:\temp\text
You can still use other tools to perform file system copies. XCOPY, ROBOCOPY and COM objects (such as the Scripting.FileSystemObject) all work in Windows PowerShell. For example, you can use the Windows Script Host Scripting.FileSystem COM class to backup.
C:\boot.ini to C:\boot.bak: (New-Object -ComObject Scripting.FileSystemObject).CopyFile('C:\boot.ini', 'C:\boot.bak')
Creating files and folders
Creating new items works the same on all Windows PowerShell providers. If a Windows PowerShell provider has more than one type of item (e.g. the FileSystem Windows PowerShell provider distinguishes between directories and files) you need to specify the item type.
This command creates a new folder C:\temp\New Folder
:
New-Item -Path 'C:\temp\New Folder' -ItemType Directory
This command creates a new empty file C:\temp\New Folder\file.txt
New-Item -Path 'C:\temp\New Folder\file.txt' -ItemType File
Important: When using the Force switch with the New-Item
command to create a folder, and the folder already exists, it won't overwrite or replace the folder. It will simply return the existing folder object. However, if you use New-Item -Force
on a file that already exists, the file will be completely overwritten.
Removing all files and folders within a folder
You can remove contained items using Remove-Item
, but you will be prompted to confirm the removal if the item contains anything else. For example, if you attempt to delete the folder C:\temp\DeleteMe
that contains other items, Windows PowerShell prompts you for confirmation before deleting the folder:
Remove-Item -Path C:\temp\DeleteMe Confirm The item at C:\temp\DeleteMe has children and the Recurse parameter was not specified. If you continue, all children will be removed with the item. Are you sure you want to continue? [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"):
If you do not want to be prompted for each contained item, specify the Recurse parameter:
Remove-Item -Path C:\temp\DeleteMe -Recurse
Mapping a local folder as a drive
You can also map a local folder, using the New-PSDrive
command. The following command creates a local drive P:
rooted in the local Program Files directory, visible only from the PowerShell session:
New-PSDrive -Name P -Root $env:ProgramFiles -PSProvider FileSystem
Just as with network drives, drives mapped within Windows PowerShell are immediately visible to the Windows PowerShell shell. In order to create a mapped drive visible from File Explorer, the parameter -Persist
is needed. However, only remote paths can be used with Persist.
Reading a text file into an array
One of the more common storage formats for text data is in a file with separate lines treated as distinct data elements. The Get-Content
cmdlet can be used to read an entire file in one step, as shown here:
PS> Get-Content -Path C:\boot.ini [boot loader] timeout=5 default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS [operating systems] multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=AlwaysOff /fastdetect multi(0)disk(0)rdisk(0)partition(1)\WINDOWS=" Microsoft Windows XP Professional with Data Execution Prevention" /noexecute=optin /fastdetect
Get-Content
already treats the data read from the file as an array, with 1 element per line of file content. You can confirm this by checking the Length of the returned content:
PS> (Get-Content -Path C:\boot.ini).Length
This command is most useful for getting lists of information into Windows PowerShell directly. For example, you might store a list of computer names or IP addresses in a file C:\temp\domainMembers.txt
, with 1 name on each line of the file. You can use Get-Content to retrieve the file contents and put them in the variable $Computers
:
$Computers = Get-Content -Path C:\temp\DomainMembers.txt
$Computers
is now an array containing a computer name in each element.
Check your knowledge
Answer these three questions about programming and scripting.
PowerShell script activities
Instructions
Watch the following video and trial a few of the scripts to test out some basic PowerShell scripts.
Share a screen capture of your attempts in the forum.
The following pages provide important tools for working in system administration. Examine the topics and scripts under each at this Microsoft Learn page. Pay particular attention to topics such as:
- The items under “Working with objects”
- Getting information about computer
- Working with VMs.
Activity
Use the new-vm cmdlet to create a new virtual machine. You will need to:
- Give the VM a name
- Specify the amount of RAM
- Create a new virtual hard disk (vhdx)
- Add a DVD drive so can install Windows.
Once you have created the VM configure by:
- Renaming to VMWS01
- Setting the IP configuration to:
- IPv4 Address: 192.168.0.50
- Subnet mask: 255.255.255.0
- Default gateway: 192.168.0.250
- DNS server: 9.9.9.9
- Set the time zone to New Zealand
- Set the region and language to New Zealand
After configuring the VM, practice collecting information for that machine such as:
- CPU
- RAM
- running processes
- Windows details
- Information about the volumes
While can use commands like read-host and write-host to put information on the screen and get it from the screen these are not very user friendly.
PowerShell's integration with .NET enables the use of forms in PowerShell scripts. The .NET Framework includes the System.Windows.Forms namespace, which provides classes for creating graphical user interfaces (GUI) with forms, controls, and events. This allows PowerShell scripts to create and customize GUI applications, build interactive forms, handle user input, and respond to events. The integration with the .NET Framework empowers PowerShell to leverage the extensive GUI capabilities of Windows Forms, enhancing the user experience and enabling the development of rich, interactive applications.
Creating a form
Take a look at the following code:
Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing $form = New-Object System.Windows.Forms.Form $form.Size = New-Object System.Drawing.Size(300,200) $form.text = 'Data Entry Form' $form.startPosition = 'CentreScreen' $form.ShowDialog()
Executing this code should display a form in the middle of the screen. At this stage, the only way to close the window, is to click the “close” in the top right corner. This will result in the word “Cancel” appearing in the output.
Starting at the top, Add-Type -AssemblyName System.Windows.Forms adds a reference to the System.Windows.Forms assembly, which provides functionality for creating Windows-based applications with forms and controls.
Add-Type -AssemblyName System.Drawing adds a reference to the System.Drawing assembly, which provides classes for graphics and image manipulation. By adding these assemblies, you can utilize the classes and functionality they provide within your PowerShell script, allowing you to create GUI applications or perform graphic-related tasks. The lines of code that follow create and configure a Windows Form object using the .NET Framework's System.Windows.Forms namespace:
- $form = New-Object System.Windows.Forms.Form creates a new instance of a Windows Form object and assigns it to the variable $form.
- $form.Size = New-Object System.Drawing.Size(300,200) sets the size of the form to 300 pixels wide and 200 pixels high using the System.Drawing.Size class.
- $form.text = 'Data Entry Form' sets the text property of the form to 'Data Entry Form', which will be displayed in the title bar of the form.
- $form.startPosition = 'CentreScreen' sets the position of the form to the centre of the screen when it is displayed.
$form.ShowDialog() displays the form as a modal dialogue box. When this line is executed, the form created earlier using the $form variable will be shown on the screen, and it will remain in focus until it is closed by the user. The script execution will pause at this point, waiting for the user to interact with the form. This behaviour allows for capturing user input or performing actions based on user interaction before the script continues executing further statements after the ShowDialog() method call.
Try changing the form.size values to see what effect it has.
Adding objects to the form
At this stage we have created a blank canvas, now we need to add some item. The first item to be added will be an “Ok” button. The following lines of code create an "OK" button, define its properties and behavior, and add it to the form's controls collection, allowing the user to interact with the button within the form. Add the lines before $form.ShowDialog() in the script.
$okButton = New-Object System.Windows.Forms.Button $okButton.Location = New-Object System.Drawing.Point(75,120) $okButton.Size = New-Object System.Drawing.Size(75,23) $okButton.Text = 'OK' $okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK $form.AcceptButton = $okButton $form.Controls.Add($okButton)
- $okButton = New-Object System.Windows.Forms.Button creates a new instance of a button control and assigns it to the variable $okButton.
- $okButton.Location = New-Object System.Drawing.Point(75,120) sets the position of the button on the form using the System.Drawing.Point class.
- $okButton.Size = New-Object System.Drawing.Size(75,23) sets the size of the button using the System.Drawing.Size class.
- $okButton.Text = 'OK' sets the text displayed on the button to 'OK'.
- $okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK sets the dialog result of the button to OK, which indicates that when the button is clicked, the dialog result of the form will be set to OK.
- $form.AcceptButton = $okButton sets the form's accept button, which determines which button is triggered when the user presses the Enter key.
- $form.Controls.Add($okButton) adds the button control to the form's collection of controls, making it visible on the form.
Try changing the values for size and location to see what effect they have.
If the user changes their mind, we need to provide an opportunity to cancel. This is done by adding a second button. Compare the code below to the code for the OK button to see how it provides different information to the script.
$cancelButton = New-Object System.Windows.Forms.Button $cancelButton.Location = New-Object System.Drawing.Point(150,120) $cancelButton.Size = New-Object System.Drawing.Size(75,23) $cancelButton.Text = 'Cancel' $cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel $form.CancelButton = $cancelButton $form.Controls.Add($cancelButton)
The form is now functional with an OK and cancel button but does not have any way of allowing user input. The following lines of code create a TextBox control, define its position and size, and adds it to the form's controls collection. This allows the user to input text within the TextBox control on the form.
$textBox = New-Object System.Windows.Forms.TextBox $textBox.Location = New-Object System.Drawing.Point(10,40) $textBox.Size = New-Object System.Drawing.Size(260,20) $form.Controls.Add($textBox)
- $textBox = New-Object System.Windows.Forms.TextBox creates a new instance of a TextBox control and assigns it to the variable $textBox.
- $textBox.Location = New-Object System.Drawing.Point(10,40) sets the position of the TextBox control on the form using the System.Drawing.Point class.
- $textBox.Size = New-Object System.Drawing.Size(260,20) sets the size of the TextBox control using the System.Drawing.Size class.
- $form.Controls.Add($textBox) adds the TextBox control to the form's collection of controls, making it visible on the form.
You can use label text on your window to describe the information you want users to provide. The following lines of code create a Label control, define its position, size, and text, and add it to the form's controls collection. The Label control displays a descriptive text message on the form, providing guidance or information to the user. Add these lines above the textbox code.
$label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(10,20) $label.Size = New-Object System.Drawing.Size(280,20) $label.Text = 'Please enter the information in the space below:' $form.Controls.Add($label)
- $label = New-Object System.Windows.Forms.Label creates a new instance of a Label control and assigns it to the variable $label.
- $label.Location = New-Object System.Drawing.Point(10,20) sets the position of the Label control on the form using the System.Drawing.Point class.
- $label.Size = New-Object System.Drawing.Size(280,20) sets the size of the Label control using the System.Drawing.Size class.
- $label.Text = 'Please enter the information in the space below:' sets the text displayed on the Label control to 'Please enter the information in the space below:'.
- $form.Controls.Add($label) adds the Label control to the form's collection of controls, making it visible on the form.
To finish the form, add the following lines after the textbox code.
$form.Topmost = $true $form.Add_Shown({$textBox.Select()}) $result = $form.ShowDialog() if ($result -eq [System.Windows.Forms.DialogResult]::OK) { $x = $textBox.Text $x }
- $form.Topmost = $true sets the Topmost property of the form to true, ensuring that the form is displayed as the topmost window on the screen.
- $form.Add_Shown({$textBox.Select()}) attaches an event handler to the form's Shown event. When the form is shown, the event handler selects the $textBox control, placing the cursor in the text box for user input.
- $result = $form.ShowDialog() displays the form as a modal dialog box, waits for the user to interact with the form, and assigns the dialog result (OK, Cancel, etc.) to the $result variable.
- The if ($result -eq [System.Windows.Forms.DialogResult]::OK) statement checks if the user clicked the OK button or pressed Enter (assuming OK is the form's AcceptButton). If true, the code block within the if statement is executed.
- $x = $textBox.Text assigns the text entered in the $textBox control to the variable $x.
- $x outputs the value of $x, displaying the entered text or performing further operations with it.
Your completed script should look like this.
Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing $form = New-Object System.Windows.Forms.Form $form.Text = 'Data Entry Form' $form.Size = New-Object System.Drawing.Size(300,200) $form.StartPosition = 'CenterScreen' $okButton = New-Object System.Windows.Forms.Button $okButton.Location = New-Object System.Drawing.Point(75,120) $okButton.Size = New-Object System.Drawing.Size(75,23) $okButton.Text = 'OK' $okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK $form.AcceptButton = $okButton $form.Controls.Add($okButton) $cancelButton = New-Object System.Windows.Forms.Button $cancelButton.Location = New-Object System.Drawing.Point(150,120) $cancelButton.Size = New-Object System.Drawing.Size(75,23) $cancelButton.Text = 'Cancel' $cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel $form.CancelButton = $cancelButton $form.Controls.Add($cancelButton) $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(10,20) $label.Size = New-Object System.Drawing.Size(280,20) $label.Text = 'Please enter the information in the space below:' $form.Controls.Add($label) $textBox = New-Object System.Windows.Forms.TextBox $textBox.Location = New-Object System.Drawing.Point(10,40) $textBox.Size = New-Object System.Drawing.Size(260,20) $form.Controls.Add($textBox) $form.Topmost = $true $form.Add_Shown({$textBox.Select()}) $result = $form.ShowDialog() if ($result -eq [System.Windows.Forms.DialogResult]::OK) { $x = $textBox.Text $x }
https://app.acilearning.com/course/powershell-2017/2017-basic-syntaxhelp
https://learn.microsoft.com/en-us/training/paths/powershell/
https://www.tutorialspoint.com/powershell/index.htm
https://www.netwrix.com/powershell_tutorial_pdf.html
Sample scripts for system administration - PowerShell | Microsoft Learn
Collecting information about computers - PowerShell | Microsoft Learn