PowerShell Fast Track Hacks For Non-Coders
PowerShell Fast Track Hacks For Non-Coders
Fast Track
Hacks for Non-Coders
—
Vikas Sukhija
PowerShell Fast Track
Hacks for Non-Coders
Vikas Sukhija
PowerShell Fast Track: Hacks for Non-Coders
Vikas Sukhija
Waterloo, ON, Canada
iii
Table of Contents
iv
Table of Contents
Chapter 8: Reporting��������������������������������������������������������������������������77
CSV Report����������������������������������������������������������������������������������������������������������77
Excel Reporting���������������������������������������������������������������������������������������������������80
HTML Reporting��������������������������������������������������������������������������������������������������85
Summary������������������������������������������������������������������������������������������������������������90
v
Table of Contents
Index�������������������������������������������������������������������������������������������������133
vi
About the Author
Vikas Sukhija has over a decade of IT
infrastructure experience with expertise in
messaging, collaboration, and IT automation
utilizing PowerShell, PowerApps , Power
Automate, and other tools. He is currently
working as a Global Director at Golden Five
Consulting in Canada. He is also a blogger,
architect, and Microsoft MVP. He is known by
the name TechWizard. As an experienced professional, he assists small to
large enterprises in architecting, implementing, and automating Microsoft
365 and Azure.
vii
About the Technical Reviewer
Arun Sharma is a techno-strategic leader
and carries deep experience in development
consulting, cloud, AI, and the IoT space. He
is currently associated with Fresh & Pure, an
agritech startup, in the position of Director
Program Management-Automation and AI.
He has expertise in various technologies
(Microsoft Azure, AWS, Ali Cloud), IoT,
ML, microservices, bots, Dynamics 365,
PowerPlatform, SAP Crystal Reports, DevOps,
Docker, and containerization. He has more
than 20 years of experience in a wide range of
roles such as GM-Paytm, Delivery Manager
at Microsoft, Product Manager at Icertis, Lead and Architect Associate at
Infosys, Executive Trainer at Aptech, and Development Consultant
at CMC. He has managed CXO-level relationships on strategic levels, sales,
cloud consumption, consulting services, and adoption with medium- and
large-size global customers.
ix
Introduction
This small book is full of small scripts that can be used by system
administrators to improve the efficiency of their day-to-day IT operations.
PowerShell Fast Track is for experienced IT administrators who want to
utilize scripting and implement IT automations. Just copy/paste code
blocks from the book/links to make simple to complex scripts. You can
consider it your own personal scripting cheat book, like the cheat codes
gamers utilize to ace electronic games. What it really is, however, is a
practical guide, because it will get you started in automating much of
your work.
xi
CHAPTER 1
PowerShell Basics
Let’s start with basic elements and quickly review variables, loops,
if/else statements, switches, and functions. These are the heart of
any scripting language, and will assist you in creating simple to
complex scripts.
I will not delve into PowerShell versions or what PowerShell is.
(But here is an easy-to-understand definition without going into depth:
PowerShell is a task automation solution made up of a command-line shell
and a scripting language.) I also won’t talk about what platforms it can be
used on or get and set commands, because this is not an in-depth book for
learning the language.
The intent of this book is to teach you how to create scripts without
having a deep knowledge of under-the-hood elements. This is an
approach I’ve used successfully with many students. They gradually
became well-versed with the language.
Not everyone is from a programming background and not everyone is
adept at creating code. However, by following the approach described in
this book, you will be able to quickly create your own scripts and automate
IT systems/processes.
Note All source code used in the book can be accessed by clicking
the Download Source Code button located at www.apress.com/
9781484277584 (follow the listing numbers).
V
ariables and Printing
To begin, you need to understand the basics, which include variables and
arrays. Every variable in PowerShell starts with a dollar sign ($), such as
$a = "1"
$b = "Vikas"
2
Chapter 1 PowerShell Basics
$b = "A","B","C","D","E"
3
Chapter 1 PowerShell Basics
$c= @("server1","server2")
A dynamic array can be defined as @(). You will use this type in
examples in this book to add elements in the array and generate reports:
$d = @()
I f/Else Switch
If else is condition-based processing. It is the basis of any scripting
language. If some condition is true, you need to process something;
otherwise, process some other thing.
Listing 1-1 shows two examples. First, you define a variable value as
10 and then you use the conditional operators and if else statements to
check if it’s greater than 9 or if it’s less than 9. Based on the result, you use
Write-host to print it to screen as shown in Figure 1-5.
Note that -gt means greater than and -lt means less than. Do not
worry; I will quickly go through them in the next subsection.
4
Chapter 1 PowerShell Basics
Yes, [int] that means integer. If you use a prefix before the variable, it
means you have exclusively defined it as an integer. Defining it is always
better but if you don’t, PowerShell is intelligent enough to do it implicitly.
These are called datatypes, and they include [string], [char], [int], [array], etc.
Listing 1-2 and Figure 1-6 show a less than operator usage snippet.
Listing 1-2. Example Code for the Less Than Operator Usage in
If/Else
[int]$a= "10"
5
Chapter 1 PowerShell Basics
Conditional/Logical Operators
Below is a list of conditional/logical operators that you will use in your
everyday scripts. Without them, many scripting operations would not be
possible. They will always be used in comparison if else statements as
shown in the above parent section.
-eq Equal
6
Chapter 1 PowerShell Basics
L ogical Operators
-and Logical AND
-or Logical OR
! Logical NOT
Logical operators are used when you want to combine the conditions.
Let’s update the above example to the code shown in Listing 1-3. You will
print true if the value of variable $a is less than 9 or equals to 10. Here you
have combined two conditions. Since it is the OR operator, TRUE will be
returned if one of them matches. Here the second condition, $a -eq "10",
matches if a value is equal to 10. See the results in Figure 1-7.
[int]$a= "10"
7
Chapter 1 PowerShell Basics
If you use the AND operator, then both conditions should match if
you want to return TRUE, which will not happen in the above case. See
Listing 1-4 and Figure 1-8.
[int]$a= "10"
L oops
There are two main loops in any scripting language and that is true for
PowerShell as well. There are others but they are all variants of these two.
8
Chapter 1 PowerShell Basics
• foreach-object
• for
$x=@("1","2","3",,"4")
9
Chapter 1 PowerShell Basics
$x | foreach-object
$x=@("1","2","3",,"4")
$x | foreach-object{
if ($_ -lt 2) { write-host "$_ is Green"
-foregroundcolor Green
}
else{ write-host "$_ is yellow" -foregroundcolor yellow
}
}
10
Chapter 1 PowerShell Basics
for: This is the one you will remember from your school days. I have
not used it much and see less usage across the community. See the code in
Listing 1-7 and the results in Figure 1-11.
11
Chapter 1 PowerShell Basics
W
hile Loop
The while loop is different because it lasts until the condition is true. Let’s
go through some examples to get more clarity.
The while loop also has two iterations:
• do-while
• while
Note You are doing the thing first and matching the condition later.
$x= 0
Do {$x++
12
Chapter 1 PowerShell Basics
For while, you are also doing something until some condition is
met. In Listing 1-9, variable x = 0 and inside the variable you increment
its value until it is not equal to 4.
Note You are checking first and doing the thing after that.
The main difference between the two, as you can see, is the while loop
(an example of which is shown in Listing 1-9) checks the condition before
the loop (iteration) but do-while does the checks after the execution. See
Figure 1-13 for the result.
13
Chapter 1 PowerShell Basics
$x= 0
F unctions
Functions are entities that, once defined, can be called anywhere in the
script. Using functions avoids repetitive, lengthy code. Here’s a glimpse for
better understanding. I will not go in any details about parametrization
and advanced functionalities of a function as my main motive here is a
little bit of understanding and combining the code together to get the work
done. In Listing 1-10, you create an Add function to add two numbers. The
result is shown in Figure 1-14.
14
Chapter 1 PowerShell Basics
Similarly, you can create this for three or more numbers. See Listing 1-11
and Figure 1-15.
15
Chapter 1 PowerShell Basics
Summary
In this chapter, you learned about PowerShell basics such as variables,
arrays, if/else statements, and loops, which are the building blocks for
creating powerful scripts in a production environment. These basics will
be utilized further in the following chapters.
16
CHAPTER 2
get-date -format d
Listing 2-1 shows the date and time used in a file name.
Listing 2-1. Code for Date and Time Used in a File Name
$m = get-date
$month = $m.month #getting month
$year = $m.year #getting year
#based on date
$log1 = ".\Processed\Logs" + "\" + "skipcsv_" + $date + "_.log"
18
Chapter 2 Date and Logs
D
ate Manipulation
You saw that get-date can get you the current date and time. You can
manipulate it according to the needs of your scripting solution. Here I will
demonstrate briefly how to perform operations such as getting the first and
last day of the month and getting a midnight date time stamp.
To get the first and last day of the month, you can use the code in
Listing 2-2. See Figure 2-3 for the results.
Listing 2-2. Code for Fetching the First and Last Day of the Month
$start = $date
$end = $lastday
19
Chapter 2 Date and Logs
Figure 2-3. Showing the first and last day of the month
To get the midnight stamp, simply use this one-liner (and see Figure 2-4):
Get-Date -Hour 0 -Minute 0 -Second 0
Figure 2-4. Showing how to get the midnight date time stamp
20
Chapter 2 Date and Logs
21
Chapter 2 Date and Logs
22
Chapter 2 Date and Logs
function New-FolderCreation
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
[string]$foldername
)
$logpath = (Get-Location).path + "\" + "$foldername"
$testlogpath = Test-Path -Path $logpath
if($testlogpath -eq $false)
{
#Start-ProgressBar -Title "Creating $foldername folder"
-Timer 10
$null = New-Item -Path (Get-Location).path -Name
$foldername -Type directory
}
}#New-FolderCreation
function Write-Log
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true,ParameterSetName = 'Create')]
[array]$Name,
[Parameter(Mandatory = $true,ParameterSetName = 'Create')]
[string]$Ext,
[Parameter(Mandatory = $true,ParameterSetName = 'Create')]
[string]$folder,
23
Chapter 2 Date and Logs
24
Chapter 2 Date and Logs
To create a log file, you can simply use it as below (it will auto-create
the folders):
To create a CSV file for report purposes, you can use it like so:
25
Chapter 2 Date and Logs
The log file is created is under the logs folder and will create a
structural log text as shown in Figure 2-7.
26
Chapter 2 Date and Logs
Figure 2-7. Log file created after using the Write-Log function
function Set-Recyclelogs
{
[CmdletBinding(
SupportsShouldProcess = $true,
ConfirmImpact = 'High')]
param
(
[Parameter(Mandatory = $true,ParameterSetName = 'Local')]
[string]$foldername,
[Parameter(Mandatory = $true,ParameterSetName = 'Local')]
[Parameter(Mandatory = $true,ParameterSetName = 'Path')]
[Parameter(Mandatory = $true,ParameterSetName = 'Remote')]
27
Chapter 2 Date and Logs
[int]$limit,
)
switch ($PsCmdlet.ParameterSetName) {
"Local"
{
$path1 = (Get-Location).path + "\" + "$foldername"
if ($PsCmdlet.ShouldProcess($path1 , "Delete"))
28
Chapter 2 Date and Logs
{
Write-Host "Path Recycle - $path1 Limit - $limit"
-ForegroundColor Green
$limit1 = (Get-Date).AddDays(-"$limit") #for report
recycling
$getitems = Get-ChildItem -Path $path1 -recurse -file |
Where-Object {$_.CreationTime -lt $limit1}
ForEach($item in $getitems){
Write-Verbose -Message "Deleting item $($item.
FullName)"
Remove-Item $item.FullName -Force
}
}
}
"Remote"
{
$path1 = "\\" + $ComputerName + "\" + $DriveName + "$" +
"\" + $folderpath
if ($PsCmdlet.ShouldProcess($path1 , "Delete"))
{
Write-Host "Recycle Path - $path1 Limit - $limit"
-ForegroundColor Green
$limit1 = (Get-Date).AddDays(-"$limit") #for report
recycling
$getitems = Get-ChildItem -Path $path1 -recurse -file |
Where-Object {$_.CreationTime -lt $limit1}
ForEach($item in $getitems){
Write-Verbose -Message "Deleting item $($item.FullName)"
Remove-Item $item.FullName -Force
}
}
}
29
Chapter 2 Date and Logs
"Path"
{
$path1 = $folderlocation
if ($PsCmdlet.ShouldProcess($path1 , "Delete"))
{
Write-Host "Path Recycle - $path1 Limit - $limit"
-ForegroundColor Green
$limit1 = (Get-Date).AddDays(-"$limit") #for report
recycling
$getitems = Get-ChildItem -Path $path1 -recurse -file |
Where-Object {$_.CreationTime -lt $limit1}
ForEach($item in $getitems){
Write-Verbose -Message "Deleting item $($item.FullName)"
Remove-Item $item.FullName -Force
}
}
}
}
}# Set-Recycle logs
To recycle logs older than 10 days inside the logs folder in the current
directory:
Use confirm:$false to avoid confirmation once you are sure that you
want to delete the files:
30
Chapter 2 Date and Logs
You can specifiy the path as well if your script is in another directory
and you want to delete logs in another folder structure:
function Start-ProgressBar
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
$Title,
[Parameter(Mandatory = $true)]
[int]$Timer
)
31
Chapter 2 Date and Logs
You can use a simple timeout as well, which is built in (see Figure 2-9):
timeout 10
S
ummary
In this chapter, you learned about the date and logs cmdlet and how to
manipulate and use the format of dates to generate time-stamped folders
and files. This technique will help you in different scenarios such as
creating log files or log folders every day with a date/time stamp inserted
into the file name.
32
CHAPTER 3
I mport-CSV
Import-CSV is the most-used method for providing a script with a CSV file
to read and it is further used to perform bulk operations using loops.
To demonstrate, let’s create a small CSV file (save it as samplecsv.csv)
in the format shown in Figure 3-1 and then print the contents. See
Listing 3-1 for the code.
34
Chapter 3 Input to Your Scripts
Save the code in a .ps1 file and run it or just paste it in the PowerShell
console. See Figure 3-4.
35
Chapter 3 Input to Your Scripts
$servers = @("server01","server02","server03","server04")
#array of servers
$servers | foreach-object {
Write-host $_ -foregroundcolor yellow
}
S
ummary
In this chapter, you learned how to feed scripts with input either through
a text file, CSV file, or an array. There are advanced ways to input your
scripts but the ways mentioned in this chapter are common and are used
every day in the system administration world.
36
CHAPTER 4
Interactive Input
This chapter will provide examples where you can add interactive input to
your scripts (i.e., the script will ask for input such as entering a password or
another attribute such as the path of a CSV or text file).
R
ead-host
You have used Write-host for printing value to the screen. Now you can
use Read-host to get values that are input by a user on the screen:
38
Chapter 4 Interactive Input
P
arameters
In a PowerShell command, functions are scripts that rely on parameters so
that a user can either enter values or select options. I will briefly touch on
basic parametrization. (Advanced parameters are outside the scope of this
book.) See Listing 4-1.
Param(
[string]$firstname,
[string]$lastname,
[string]$title
)
Save this as a .ps1 file and run it as follows (and see Figure 4-4):
Tip Make sure you define the parameters at the beginning of your
script.
39
Chapter 4 Interactive Input
G
UI Button
Here is a cheat code (function) in case you want interactive input in the
form of a graphical user interface. I consider it as a fancy way to get input
from the user. The button function in Listing 4-2 can take inputs from the
Windows form that you can display on a screen or perform other desired
operations in your script.
$textLabel1.Text = $mailbx;
40
Chapter 4 Interactive Input
$textLabel2.Text = $WF;
$textLabel3.Text = $TF;
41
Chapter 4 Interactive Input
#############define OK button
$button = New-Object "System.Windows.Forms.Button";
$button.Left = 360;
$button.Top = 85;
$button.Width = 100;
$button.Text = "Ok";
$button.Add_Click($eventHandler) ;
42
Chapter 4 Interactive Input
#################return values
Load this function into your script, and then you can perform the
operations on the inputs as shown:
You can choose different names per your requirements. See Figure 4-5.
After you press the OK button, the $return variable contains all these
values in the array (see Figure 4-6):
43
Chapter 4 Interactive Input
You can also print to the screen in the same manner as shown
previously (see Figure 4-7):
Figure 4-7. Printing the values from the input using Write-host
44
Chapter 4 Interactive Input
Copy and paste the code into the PowerShell console or save the script
as a .ps1 file and run it. See Figure 4-8.
If you press Yes, you get the result shown in Figure 4-9.
45
Chapter 4 Interactive Input
If you press No, you get the result shown in Figure 4-10.
S
ummary
In this chapter, you learned about interactive inputs. This strategey is
utilized when you have to provide the script to an end user. The end user
can just run the script. Questions that are coded by the scripter pop up
interactively and the user can answer them and perform a meaningful job.
46
CHAPTER 5
Adding Snapins/
Modules
Microsoft and other third-party vendors have built PowerShell snapins
or modules for their different products. To use the PowerShell cmdlets
for these technologies, you have to either add the snapins or import the
modules in your scripts.
PowerShell snapins are legacy products because nowadays everything
comes as modules. You can consider a module as a battery that is required
to run your scripts. Each module is a package that contains cmdlets,
providers, functions, aliases, and more.
Although snapins are legacy, let’s touch on them briefly, showing the
products that use(d) them.
P
owerShell Snapins
Exchange Sever itself is the better example to show for PowerShell snapins.
Exchange 2007 and 2010 both used snapins.
To add an Exchange snapin to your scripts, you can use following
code. (Examples of Exchange 2007 and 2010 snapins are in Listing 5-1 and
Listing 5-2, respectively.) As these products are officially at end-of-support
status, the usage might be rare (they’re only applicable for organizations
that have not upgraded yet).
After the snapin has been added to the session or the script, it can run
the Exchange commands inside the window, as shown in Figure 5-1.
48
Chapter 5 Adding Snapins/ Modules
Listing 5-3 shows how to add the snapin to the PowerShell script or
session using the same technique as for the Exchange product.
49
Chapter 5 Adding Snapins/ Modules
M
odules
Let’s cover modules now as this is what you will deal with in your day-to-
day work. Per Microsoft, “a module is a package that contains PowerShell
members, such as cmdlets, providers, functions, workflows, variables, and
aliases. The members of this package can be implemented in a PowerShell
script, a compiled DLL, or a combination of both. These files are usually
grouped together in a single directory.”
For the PowerShell scripting language, we need modules to interact with
different products, such as Azure, Office 365, Exchange Online, and so on.
PowerShell Gallery (www.powershellgallery.com/) is the de facto
repository that contains almost all of the modules that anyone can utilize.
To install a module on your machine from PowerShell gallery, use this
code:
Enter yes (as shown in Figure 5-3) when you receive the prompt to
install the module.
When you install the module on your machine it will get stored in
C:\Program Files\WindowsPowerShell\Modules as depicted in Figure 5-4.
50
Chapter 5 Adding Snapins/ Modules
or
With update you can also update the module to a specific version:
Remove-Module AzureAD
After you have installed the module, which is a one-time task, and
you want to utilize that module in your scripts, you can do so by using the
Import-Module command.
51
Chapter 5 Adding Snapins/ Modules
You can still follow the practice of importing the modules in your script
before running a command:
Import-Module AzureAD
To get all of the modules installed on your machine, you can use the
following code (the results are shown in Figure 5-5):
Get-Module -ListAvailable
52
Chapter 5 Adding Snapins/ Modules
Once installed, you will find files created inside your module’s
directory (C:\Program Files\WindowsPowerShell\Modules) as depicted
in Figure 5-7.
As stated, you can import the module in to the session using import-
module like so:
import-module vsadmin
Figure 5-8 shows the commands that are available inside the vsadmin
module. You can use the following command to check functions and
cmdlets in any module:
53
Chapter 5 Adding Snapins/ Modules
Let’s explore Office 365 functions and then we will move on to other
system admin functions that you can utilize daily.
54
Chapter 5 Adding Snapins/ Modules
Three of the Office 365 functions are prefixed so that they do not
conflict with on-premise commands and are easy to use/understand in a
hybrid script. For example, the Exchange Online command get-mailbox is
get-EOLmailbox when you use this module to launch it, as shown later.
Note The following native Office 365 modules are necessary for the
Office 365 functions in the vsadmin module to work, or it will ask
you to install them.
• ExchangeOnlineManagement, www.
powershellgallery.com/packages/
ExchangeOnlineManagement
55
Chapter 5 Adding Snapins/ Modules
Figure 5-10 shows that you are connected and can use the Exchange
commands.
56
Chapter 5 Adding Snapins/ Modules
RemoveEOL/RemoveSOL/RemoveSPO, etc.
Other good functions that system administrators really like are the
LaunchEXOnprem/RemoveEXOnprem functions as they are for on-premise
Exchange servers. To connect to an Exchange on-premise server from your
network, use this code:
or
57
Chapter 5 Adding Snapins/ Modules
To disconnect, use the same technique you used for Office 365
functions:
Import-Module vsadmin
58
Chapter 5 Adding Snapins/ Modules
I will not get into the other functions that have been shared in previous
chapters. I just wanted to show that they can all be used in this manner as
well.
59
Chapter 5 Adding Snapins/ Modules
or
60
Chapter 5 Adding Snapins/ Modules
Let’s use a small cheat code snippet to connect to Office 365 using the
PS credentials saved in the file and export a CSV report on mailboxes. (This
can be modified and scheduled as per your needs.) See Listing 5-5 and
Figure 5-14.
Import-Module vsadmin
61
Chapter 5 Adding Snapins/ Modules
Use Get-IniContent to read ini files and then use the values in scripts.
See Figure 5-15.
$inifile = "c:\temp\config.ini"
$readini = Get-IniContent $inifile
$User = $readini["ServiceAccount"].UserID
62
Chapter 5 Adding Snapins/ Modules
New-RandomPassword – NumberofChars 9
63
Chapter 5 Adding Snapins/ Modules
Last but not least, I’ll share some Active Directory functions that are
not available out of the box from the Active Directory module.
Get-ADGroupMembersRecursive can extract group members
recursively, but the AD module is required:
S
ummary
In this chapter, you learned how to use modules in PowerShell. Modules
are like batteries. Without them it is hard to script any product using
PowerShell. I also shared a cheat system administration module (vsadmin)
which has many daily use functions/cmdlets.
64
CHAPTER 6
Sending Email
Sending email is an important aspect of scripting. Say you want to send
alerts if a script results in an error, or you want to send bulk emails without
utilizing any bulk email tool.
PowerShell has a simple and effective out-of-the-box cmdlet for this
purpose right from PowerShell v2. The following is an example of Send-
MailMessage, which is prevalent in PowerShell:
If you are still using PowerShell 1.0 (which is highly unlikely), you can
use the code in Listing 6-1 as it works on all versions of PowerShell.
$smtpserver = "smtp.lab.com"
$to = "[email protected]"
$from = "[email protected]"
$file = "c:\file.txt" #for attachment
$subject = "Test Subject"
$message.To.Add($to)
$smtpserver = "smtp.lab.com"
$to = "[email protected]"
$from = "[email protected]"
$subject = "Test Subject"
$message = @"
Hello,
Line............................1
Line............................2
Line............................3
"@
Send-MailMessage -SmtpServer $smtpserver -From $from -To $to
-Subject $subject -Body $message
66
Chapter 6 Sending Email
S
ending HTML
You can send fancy HTML emails using PowerShell if you use another cheat
tip if you are not familiar with HTML. Log on to the HTML Online Editor
(shown in Figure 6-2) to create the HTML: https://html-online.com/
editor/.
67
Chapter 6 Sending Email
Create some HTML content and use the code in Listing 6-3. You can
see the result in Figure 6-3.
$smtpserver = "smtp.lab.com"
$to = "[email protected]"
$from = "[email protected]"
$subject = "Test Subject"
$message = @"
<!-- ####### YAY, I AM THE SOURCE EDITOR! #########-->
<h1 style="color: #5e9ca0;">You can edit <span style="color:
#2b2301;">this demo</span> text!</h1>
<h2 style="color: #2e6c80;">How to use the editor:</h2>
<p>Paste your documents in the visual editor on the left or
your HTML code in the source editor in the right. <br />Edit
any of the two areas and see the other changing in real
time. </p>
68
Chapter 6 Sending Email
<p> </p>
"@
S
ummary
In this chapter, you learned how to send email using PowerShell. You can
use this knowledge in the real world to send bulk emails or send email
alerts when some task/process/script fails or errors out.
69
CHAPTER 7
Error Reporting
For successful scripting, error reporting is a must-have. If there is an error,
you want to report it to the admin or the owner of the process/automation.
PowerShell has different ways to do error reporting. The most common
way is the $error variable as it contains all the errors that have occurred
in the session. Let’s look at some cheat code examples that you can utilize.
You can log errors or send them via email.
$from = "[email protected]"
$to="[email protected]"
$subject = "Error has occured"
$smtpServer="smtp.lab.com"
if ($error)
{
Send-MailMessage -SmtpServer $smtpserver -From $from -To $to
-Subject $subject -Body $error[0].ToString()
$error.clear()
}
Listing 7-1 is missing one important thing. It just sends the last error,
but what if you want to send the full error, which is actually an array and
send-mailmessage is not able to send it effectively? You can utilize the
Send-Email function in Listing 7-2, which is also part of the vsadmin
module that was shared in the modules chapter.
function Send-Email
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true)]
$From,
[Parameter(Mandatory = $true)]
[array]$To,
[array]$bcc,
[array]$cc,
$body,
$subject,
$attachment,
[Parameter(Mandatory = $true)]
$smtpserver
)
72
Chapter 7 Error Reporting
73
Chapter 7 Error Reporting
{
$attach = New-Object Net.Mail.Attachment($attachment)
$message.Attachments.Add($attach)
}
if ($body -ne $null)
{$message.body = $body}
$smtp = New-Object Net.Mail.SmtpClient($smtpserver)
$smtp.Send($message)
}
Once you have imported the function from Listing 7-2, you can utilize
the code in Listing 7-3, which is similar to the code in Listing 7-1. The only
change is utilizing Send-Email instead of the built-in Send-MailMessage.
$from = "[email protected]"
$to="[email protected]"
$subject = "Error has occured"
$smtpServer="smtp.lab.com"
if ($error)
{
Send-Email -smtpserver $smtpServer -From $from -To $to
-subject $subject -body $error
$error.clear()
}
74
Chapter 7 Error Reporting
$log = "c:\data\log.txt"
Start-transcript -path $log # at the beginning of the script
Stop-transcript # at the end of the script
75
Chapter 7 Error Reporting
Summary
In this chapter, you learned how to report errors when they occur, how
to write them in log files, how to send them through email, and how to
capture the whole PowerShell session with the start-transcript cmdlet.
76
CHAPTER 8
Reporting
Reports are an important aspect of day-to-day system administration.
Sometimes we present reports to our managers and other times we utilize
them to evaluate and improve our own work.
Reports can be in the form of CSV, HTML, Excel, and more. The most
common form is a CSV report because it’s universal and can be converted
to other forms like Excel easily from the application itself.
C
SV Report
Export-CSV is the built-in PowerShell cmdlet that can be used to export
the data to a CSV file. You can simply pipe select and then export as
shown in the following code that shows the export of certain attributes of
users’ mailboxes from Exchange Server (to be run in the Exchange shell):
There are many complex situations where you need scripting code to
format the data in the right manner. Listing 8-1 and Figure 8-1 show where
you have a list of users in a text file and you want to export their Active
Directory attributes and some Exchange attributes in a CSV file. In this
case, get, select, and export are not possible. This code can be used in all
such situations where you want to export the data in the CSV form but a
simple operation is not possible.
Note The Exchange and AD modules are both required. You need to
connect to them. The script will fail if they are not loaded.
Import-Module Activedirectory
78
Chapter 8 Reporting
$coll.IssueWarningQuota = $getmbx.IssueWarningQuota
$coll.employeeid = $getaduser.employeeid #note difference here
$coll.l = $getaduser.l
$coll.c = $getaduser.c
$collection+=$coll #add the collected values to the collecttion
array
}
#now export to CSV file
$collection | Export-Csv .\report.csv -NoTypeInformation
79
Chapter 8 Reporting
@{Name="Recipents";Expression={$_.recipients}}
E xcel Reporting
Although CSV reports are fine for most purposes, there are situations in
which you want to share the data with your managers so converting the
CSV file to Excel is a much-needed script. I will share two methods for
doing the same.
The first method exists in the vsadmin module that was shared in the
modules chapter.
80
Chapter 8 Reporting
Listing 8-3 shows the code of the Save-CSV2Excel function in case you
do not have the vsadmin module installed or do not want to use it.
Function Save-CSV2Excel
{
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true,Position = 1)]
[ValidateScript({
if(-Not ($_ | Test-Path) ){throw "File or folder does
not exist"}
if(-Not ($_ | Test-Path -PathType Leaf) ){throw "The
Path argument must be a file. Folder paths are not
allowed."}
if($_ -notmatch "(\.csv)"){throw "The file specified
in the path argument must be either of type csv"}
return $true
})]
[System.IO.FileInfo]$CSVPath,
[Parameter(Mandatory = $true)]
[ValidateScript({
if($_ -notmatch "(\.xlsx)"){throw "The file specified
in the path argument must be either of type xlsx"}
return $true
})]
[System.IO.FileInfo]$Exceloutputpath
)
####### Borrowed function from Lloyd Watkinson from script
gallery##
Function Convert-NumberToA1
81
Chapter 8 Reporting
{
Param([parameter(Mandatory = $true)]
[int]$number)
$a1Value = $null
While ($number -gt 0)
{
$multiplier = [int][system.math]::Floor(($number / 26))
$charNumber = $number - ($multiplier * 26)
If ($charNumber -eq 0) { $multiplier-- ; $charNumber = 26
}
$a1Value = [char]($charNumber + 64) + $a1Value
$number = $multiplier
}
Return $a1Value
}
##################Start converting
excel#######################
$importcsv = Import-Csv $CSVPath
$countcolumns = ($importcsv |
Get-Member |
Where-Object{$_.membertype -eq "Noteproperty"}).count
#################call Excel com object ##############
$xl = New-Object -comobject excel.application
$xl.visible = $false
$Workbook = $xl.workbooks.open($CSVPath)
$Workbook.SaveAs($Exceloutputpath, 51)
$Workbook.Saved = $true
$xl.Quit()
#############Now format the Excel###################
timeout.exe 10 #wait for 10 seconds before saving
$xl = New-Object -comobject excel.application
82
Chapter 8 Reporting
$xl.visible = $false
$Workbook = $xl.workbooks.open($Exceloutputpath)
$worksheet1 = $Workbook.worksheets.Item(1)
for ($c = 1; $c -le $countcolumns; $c++) {$worksheet1.Cells.
Item(1, $c).Interior.ColorIndex = 39}
$colvalue = (Convert-NumberToA1 $countcolumns) + "1"
$headerRange = $worksheet1.Range("a1", $colvalue)
$null = $headerRange.AutoFilter()
$null = $headerRange.entirecolumn.AutoFit()
$worksheet1.rows.item(1).Font.Bold = $true
$Workbook.Save()
$Workbook.Close()
$xl.Quit()
$Null = [System.Runtime.Interopservices.Marshal]::Release
ComObject($xl)
##########################################################
#############
}#Write-CSV2Excel
Let’s use the CSV report from Listing 8-1 and convert it to Excel using
Save-CSV2Excel. See Figure 8-2.
83
Chapter 8 Reporting
Let’s use the same report and use this new module to convert it into
Excel. The advantage of using this module is that it does not require Excel
to be installed on the machine. See Figure 8-3.
84
Chapter 8 Reporting
There are lot of other parameters inside that function like the
formatting of Excel, which I leave to you to explore!
H
TML Reporting
It would be wonderful if we could create HTML dashboards with
PowerShell ☺ that can show traffic light-type signals. For example, if a
service is down, it shows red. Otherwise, it shows green. See Figure 8-4.
85
Chapter 8 Reporting
Listing 8-4 is a template for HTML coding that you can use inside
scripts and do traffic light-type operations based on conditions.
$report = $reportpath
Clear-Content $report
#################HTml Report
Content############################
Add-Content $report "<html>"
Add-Content $report "<head>"
Add-Content $report "<meta http-equiv='Content-Type'
content='text/html; charset=iso-8859-1'>"
Add-Content $report '<title>Exchange Status Report</title>'
add-content $report '<STYLE TYPE="text/css">'
add-content $report "<!--"
add-content $report "td {"
add-content $report "font-family: Tahoma;"
add-content $report "font-size: 11px;"
add-content $report "border-top: 1px solid #999999;"
add-content $report "border-right: 1px solid #999999;"
add-content $report "border-bottom: 1px solid #999999;"
add-content $report "border-left: 1px solid #999999;"
86
Chapter 8 Reporting
87
Chapter 8 Reporting
88
Chapter 8 Reporting
89
Chapter 8 Reporting
See examples at the following links where this template has been
successfully utilized for the Exchange Health Check, AD Health Check, and
Monitor Remote services:
https://techwizard.cloud/exchange-2010-health-check/
https://techwizard.cloud/adhealthcheck/
https://techwizard.cloud/monitor-windows-services-status-remotely/
As mentioned, you can use the HTML Online Editor to create HTML
and use it in your PowerShell scripts (https://html-online.com/
editor/).
S
ummary
In this chapter, you learned about reporting. CSV, HTML, and Excel are
three common report types used by almost all systems. By learning how to
run these reports you can easily impress managers with the data they need
in a format that is understandable.
90
CHAPTER 9
Miscellaneous
Keywords
In this chapter, you will be introduced to keywords in PowerShell. These
keywords can perform data manipulation, which is a crucial part of any
scripting or automation operation.
In the next chapter, you will use the knowledge you have gathered in
this book to create some practical production scripts using the cheat codes
shared in this book.
S
plit
The split keyword can be used to extract data out of a string. Say there
is an email address inside a string and you want to get it, or you want to
extract some useful information out of a text string.
Let’s go through an example to understand it more. Let’s extract the
first name and last name from an email address string. You will use split
because it can split the string on any character and convert it into array.
You will split the email address on the dot (.). After that, in element 0 of
the array you get the first name, but for last name you must split again at
character @.
$email = "[email protected]"
$emsplit = $email.split(".")
$firstname = $emsplit[0]
$lastname = ($emsplit[1] -split "@")
$lastn = $lastname[0]
$emsplit[0] and $lastname[0]
R
eplace
Another keyword is replace. Instead of splitting the string, you can replace
the content of the string with other content.
92
Chapter 9 Miscellaneous Keywords
You can use replace when you want to replace data in a string. Say you
want to add an underscore instead of a dot because you want to update a
secondary address. You can use this code and see the result in Figure 9-2:
$email = "[email protected]"
$emreplace = $email.replace(".","_")
S
elect-String
Select-String can do wonders because you can use it to find strings
inside files. Here is a practical use for it, which I have used many times
(while others have struggled and spent ample hours trying to solve):
finding the right date and time of an operation from a large number of log
files.
Say you have a large number of files inside the logs folder and you just
want to find the files where the string error is present:
This simple one-liner will search for the string error in all of the log
files inside the logs folder. Figure 9-3 show how it extracted the file name
of the file that has the error.
93
Chapter 9 Miscellaneous Keywords
C
ompare-Object
Compare-Object (alias Compare) is used many times to compare two files or
two arrays. It is faster than comparing the arrays or files using for loops. I
use it many times for fetching members from a group and comparing them
with a text file that has user IDs. This approach fetches only members that
are not already part of the group and adds them, instead of processing all
members.
Listing 9-1 adds members from one group to another.
94
Chapter 9 Miscellaneous Keywords
95
Chapter 9 Miscellaneous Keywords
You can combine both operations in one script and synchronize two
groups based on group1 as the anchor. Listing 9-3 shows this operation.
96
Chapter 9 Miscellaneous Keywords
$Removal = $change |
Where-Object -FilterScript {$_.SideIndicator -eq "=>"} |
Select-Object -ExpandProperty InputObject
#######adding only members that are missing in group2########
$Addition | ForEach-Object{
$sam = $_
Add-ADGroupMember -identity "group2" -Members $sam
}
You can also use the other approach, so instead of removing from
group2 you just use ADD-Groupmember for group1 so you can truly
synchronize both groups. Any user object that is not present in group2 but
is in group1 should be added to group2, and any user object not present in
group1 but in group2 should be added to group1:
instead of
There are other nice tricks you can perform with Compare-Object. Say
you have two CSV files. One just has email addresses of users; the other has
email addresses and other properties. You want all details from CSV file 2
for the users in CSV file one.
97
Chapter 9 Miscellaneous Keywords
Listing 9-4 shows an example for OneDrive properties. There are two
CSV files. One contains user email addresses and the other contains email
addresses and other properties in other columns.
Listing 9-4. Cheat Code for Merging Two CSV Files Using Compare-
Object
$importallonedrivesites = import-csv "c:\importonedrives.csv" #
onedrive file with other attributes
$importspofile = import-csv "c:\users.csv" #users email
addresses
S
ummary
In this chapter, you learned about important keywords in PowerShell,
which will help you with data manipulation or transformation. This means
you can automate information when the data input is in a different format
than expected.
98
CHAPTER 10
<#
.NOTES
===========================================================
Created with: ISE
Created on: 9/6/2021 1:46 PM
Created by: Vikas Sukhija
Organization:
Filename: ADDUserstoGroupfromText.ps1
===========================================================
.DESCRIPTION
This will add the users from text file to AD group
#>
Step 2: Import all modules that you will utilize for this script:
1. The vsadmin module will make your life easy for the
scripting operations.
If you do not want to use the vsadmin module, then just use the
functions instead.
100
Chapter 10 Gluing It All Together
import-module vsadmin
import-module Activedirectory
101
Chapter 10 Gluing It All Together
else{
Write-Log -Message "Success - ADD $user to $Adgroup"
-path $log
}
}
}
#####################Recycle logs#############################
Set-Recyclelogs -foldername "logs" -limit $logrecyclelimit
-Confirm:$false
102
Chapter 10 Gluing It All Together
import-module vsadmin
import-module Activedirectory
$Adgroup = "ADgroup1"
$users | foreach-object{
$user = $_.trim() #triming fro any whitespace
Write-Log -Message "Processing..........$user" -path $log
$getusermemberof = Get-ADUserMemberOf -User $user -Group
$Adgroup #checking if user si already member
if($getusermemberof -eq $true){ #if users is already mebe
rjust write it to log
Write-Log -Message "$user is already member of $Adgroup"
-path $log
}
else{
Write-Log -Message "ADD $user to $Adgroup" -path $log
Add-ADGroupMember -identity $Adgroup -member $user
if($error){ #error checking, if error occurs add in log
Write-Log -Message "Error - ADD $user to $Adgroup" -path
$log
103
Chapter 10 Gluing It All Together
Let’s run this cheat code by changing the variable adgroup and adding
users in the text file as per the production environment. See Figure 10-3.
104
Chapter 10 Gluing It All Together
M
icrosoft Exchange
lean Database So That Mailboxes Appear
C
in a Disconnected State
Get-MailboxServer | Get-MailboxDatabase | Clean-MailboxDatabase
105
Chapter 10 Gluing It All Together
Message Tracking
Get-transportserver | Get-MessageTrackingLog -Start "03/09/2015
00:00:00 AM" -End "03/09/2015 11:59:59 PM" -sender "vikas@
lab.com" -resultsize unlimited | select Timestamp,clientip,
ClientHostname,ServerIp,ServerHostname,sender,EventId,Messa
geSubject, TotalBytes , SourceContext,ConnectorId,Source ,
InternalMessageId , MessageId ,@{Name="Recipents";Expressi
on={$_.recipients}} | export-csv c:\track.csv
106
Chapter 10 Gluing It All Together
Delete:
#format Date
$date = get-date -format d
$date = $date.ToString().Replace("/", "-")
$output = ".\" + "QuotaReport_" + $date + "_.csv"
Collection = @()
Get-Mailbox -ResultSize Unlimited | foreach-object{
$st = get-mailboxstatistics $_.identity
$TotalSize = $st.TotalItemSize.Value.ToMB()
107
Chapter 10 Gluing It All Together
$mbxr.DisplayName = $_.DisplayName
$mbxr.Alias = $_.Alias
$mbxr.RecipientType = $user.RecipientType
$mbxr.TotalItemSizeinMB = $TotalSize
$mbxr.QuotaStatus = $st.StorageLimitStatus
$mbxr.UseDatabaseQuotaDefaults = $_.UseDatabaseQuotaDefaults
$mbxr.IssueWarningQuota = $_.IssueWarningQuota.Value
$mbxr.ProhibitSendQuota = $_.ProhibitSendQuota.Value
$mbxr.ProhibitSendReceiveQuota = $_.ProhibitSendReceiveQuota.Value
$mbxr.Itemcount = $st.Itemcount
$mbxr.Email = $_.PrimarySmtpAddress
$mbxr.ServerName = $st.ServerName
$mbxr.Company = $user.Company
$mbxr.Hidden = $_.HiddenFromAddressListsEnabled
$mbxr.RecipientTypeDetails = $_.RecipientTypeDetails
$mbxr.OrganizationalUnit = $_.OrganizationalUnit
$mbxr.UserAccountControl = $_.UserAccountControl
$mbxr.ExchangeVersion= $_.ExchangeVersion
$Collection += $mbxr
}
#export the collection to csv , define the $output path
accordingly
$Collection | export-csv $output
108
Chapter 10 Gluing It All Together
Set Quota
1GB mailbox limit (must have the $false included):
Active Directory
Active Directory is the lifeline of every Microsoft product. By using
PowerShell you can automate various AD components. Thankfully,
Microsoft created a native Active Directory module for this job.
The following are methods that you can use for Active Directory
scripting through PowerShell:
109
Chapter 10 Gluing It All Together
110
Chapter 10 Gluing It All Together
111
Chapter 10 Gluing It All Together
$cells.item(1,10)="City"
$cells.item(1,11)="State"
$cells.item(1,12)="Country"
#intitialize row out of the loop
$row = 2
#import quest management Shell
if ( (Get-PSSnapin -Name Quest.ActiveRoles.ADManagement
-ErrorAction SilentlyContinue) -eq $null )
{
Add-PsSnapin Quest.ActiveRoles.ADManagement
}
$data = get-qaduser -IncludedProperties "CO",
"extensionattribute1" #-sizelimit 0
#loop thru users
foreach ($i in $data){
#initialize column within the loop so that it always loop back
to column 1
$col = 1
$userid=$i.Name
$FisrtName=$i.givenName
$LastName=$i.sn
$Employeeid=$i.extensionattribute1
$email=$i.PrimarySMTPAddress
$office=$i.Office
$Department=$i.Department
$Title=$i.Title
$Company=$i.Company
$City=$i.l
$state=$i.st
$Country=$i.CO
Write-host "Processing.................................$userid"
112
Chapter 10 Gluing It All Together
$cells.item($row,$col) = $userid
$col++
$cells.item($row,$col) = $FisrtName
$col++
$cells.item($row,$col) = $LastName
$col++
$cells.item($row,$col) = $Employeeid
$col++
$cells.item($row,$col) = $email
$col++
$cells.item($row,$col) = $office
$col++
$cells.item($row,$col) = $Department
$col++
$cells.item($row,$col) = $Title
$col++
$cells.item($row,$col) = $Company
$col++
$cells.item($row,$col) = $City
$col++
$cells.item($row,$col) = $state
$col++
$cells.item($row,$col) = $Country
$col++
$row++}
#formatting excel
$range = $objExcel.Range("A2").CurrentRegion
$range.ColumnWidth = 30
$range.Borders.Color = 0
$range.Borders.Weight = 2
$range.Interior.ColorIndex = 37
113
Chapter 10 Gluing It All Together
$range.Font.Bold = $false
$range.HorizontalAlignment = 3
# Headings in Bold
$cells.item(1,1).font.bold=$True
$cells.item(1,2).font.bold=$True
$cells.item(1,3).font.bold=$True
$cells.item(1,4).font.bold=$True
$cells.item(1,5).font.bold=$True
$cells.item(1,6).font.bold=$True
$cells.item(1,7).font.bold=$True
$cells.item(1,8).font.bold=$True
$cells.item(1,9).font.bold=$True
$cells.item(1,10).font.bold=$True
$cells.item(1,11).font.bold=$True
$cells.item(1,12).font.bold=$True
#save the excel file
$filepath = "c:\exportAD.xlsx" #save the excel file
$workbook.saveas($filepath)
$workbook.close()
$objExcel.Quit()
114
Chapter 10 Gluing It All Together
$cells.item(1,2)="FirstName"
$cells.item(1,3)="LastName"
$cells.item(1,4)="Employeeid"
$cells.item(1,5)="email"
$cells.item(1,6)="Office"
$cells.item(1,7)="Department"
$cells.item(1,8)="Title"
$cells.item(1,9)="Company"
$cells.item(1,10)="City"
$cells.item(1,11)="State"
$cells.item(1,12)="Country"
#intitialize row out of the loop
$row = 2
#import AD management Shell
Import-module Activedirectory
$data = Get-ADUser -Filter {Enabled -eq $True} -Properties
extensionattribute1,mail,physicalDeliveryOfficeName,Department,
title,Company,l,st,co -ResultSetSize 1000 #define the size
#loop thru users
foreach ($i in $data){
#initialize column within the loop so that it always loop back
to column 1
$col = 1
$userid=$i.Name
$FisrtName=$i.givenName
$LastName=$i.surname
$Employeeid=$i.extensionattribute1
$email=$i.mail
$office=$i.physicalDeliveryOfficeName
$Department=$i.Department
$Title=$i.Title
115
Chapter 10 Gluing It All Together
$Company=$i.Company
$City=$i.l
$state=$i.st
$Country=$i.CO
Write-host "Processing.................................$userid"
$cells.item($row,$col) = $userid
$col++
$cells.item($row,$col) = $FisrtName
$col++
$cells.item($row,$col) = $LastName
$col++
$cells.item($row,$col) = $Employeeid
$col++
$cells.item($row,$col) = $email
$col++
$cells.item($row,$col) = $office
$col++
$cells.item($row,$col) = $Department
$col++
$cells.item($row,$col) = $Title
$col++
$cells.item($row,$col) = $Company
$col++
$cells.item($row,$col) = $City
$col++
$cells.item($row,$col) = $state
$col++
$cells.item($row,$col) = $Country
$col++
$row++}
#formatting excel
116
Chapter 10 Gluing It All Together
$range = $objExcel.Range("A2").CurrentRegion
$range.ColumnWidth = 30
$range.Borders.Color = 0
$range.Borders.Weight = 2
$range.Interior.ColorIndex = 37
$range.Font.Bold = $false
$range.HorizontalAlignment = 3
# Headings in Bold
$cells.item(1,1).font.bold=$True
$cells.item(1,2).font.bold=$True
$cells.item(1,3).font.bold=$True
$cells.item(1,4).font.bold=$True
$cells.item(1,5).font.bold=$True
$cells.item(1,6).font.bold=$True
$cells.item(1,7).font.bold=$True
$cells.item(1,8).font.bold=$True
$cells.item(1,9).font.bold=$True
$cells.item(1,10).font.bold=$True
$cells.item(1,11).font.bold=$True
$cells.item(1,12).font.bold=$True
#save the excel file
$filepath = "c:\exportAD.xlsx" #save the excel file
$workbook.saveas($filepath)
$workbook.close()
$objExcel.Quit()
117
Chapter 10 Gluing It All Together
118
Chapter 10 Gluing It All Together
O
ffice 365
Office 365 is everywhere so connecting is important in day-to-day activities
for admins. You can use vsadmin or separate functions.
Operations: https://techwizard.cloud/2016/12/18/all-in-one-
office-365-powershell-connect/
[CmdletBinding()]
param
119
Chapter 10 Gluing It All Together
(
[Parameter(Mandatory = $false)]
$Credential
)
Import-Module ExchangeOnlineManagement -Prefix "EOL"
Connect-ExchangeOnline -Prefix "EOL" -Credential $Credential
-ShowBanner:$false
}
Function RemoveEOL {
Disconnect-ExchangeOnline -Confirm:$false
}
#############Skype Online#####################################
function LaunchSOL
{
param
(
[Parameter(Mandatory = $true)]
$Domain,
[Parameter(Mandatory = $false)]
$Credential
)
Write-Host -Object "Enter Skype Online Credentials"
-ForegroundColor Green
$dommicrosoft = $domain + ".onmicrosoft.com"
$CSSession = New-CsOnlineSession -Credential $Credential
-OverrideAdminDomain $dommicrosoft
Import-Module (Import-PSSession -Session $CSSession
-AllowClobber) -Prefix SOL -Global
} #Function LaunchSOL
Function RemoveSOL
120
Chapter 10 Gluing It All Together
{
$Session = Get-PSSession | Where-Object -FilterScript {
$_.ComputerName -like "*.online.lync.com" }
Remove-PSSession $Session
} #Function RemoveSOL
############Sharepoint Online###############################
function LaunchSPO
{
param
(
[Parameter(Mandatory = $true)]
$orgName,
[Parameter(Mandatory = $false)]
$Credential
)
Write-Host "Enter Sharepoint Online Credentials"
-ForegroundColor Green
Connect-SPOService -Url "https://$orgName-admin.sharepoint.
com" -Credential $Credential
} #LaunchSPO
Function RemoveSPO
{
disconnect-sposervice
} #RemoveSPO
####Secuirty and
Compliance#####################################
Function LaunchCOL {
[CmdletBinding()]
param
(
121
Chapter 10 Gluing It All Together
[Parameter(Mandatory = $false)]
$Credential
)
Import-Module ExchangeOnlineManagement
Connect-IPPSSession -Credential $Credential
$s=Get-PSSession | where {$_.ComputerName -like "*compliance.
protection.outlook.com"}
Import-Module (Import-PSSession -Session $s -AllowClobber)
-Prefix col -Global
}
Function RemoveCOL {
Disconnect-ExchangeOnline -Confirm:$false
}
###############################Msonline######################
function LaunchMSOL {
[CmdletBinding()]
param
(
[Parameter(Mandatory = $false)]
$Credential
)
import-module msonline
Write-Host "Enter MS Online Credentials" -ForegroundColor Green
Connect-MsolService -Credential $Credential
}
Function RemoveMSOL {
122
Chapter 10 Gluing It All Together
123
Chapter 10 Gluing It All Together
If you have a large tenant, use this code instead as this will not
throttle easily even with more than 50,000 users:
$index = 1
while ($index -le 1001)
{
Get-EOLMessageTrace -SenderAddress "[email protected]"
-StartDate 09/20/2019 -EndDate 09/25/2019 -PageSize 5000 -Page
$index | export-csv c:\messagetracking.csv -Append
$index ++
sleep 5
}
124
Chapter 10 Gluing It All Together
https://docs.microsoft.com/en-us/microsoft-365/compliance/
search-the-audit-log-in-security-and-compliance?WT.mc_id=M365-
MVP-5001317
A
zure AD
I have covered practical examples of Active Directory but in today’s world
Azure AD is becoming common so here are some example from the Azure
AD world.
125
Chapter 10 Gluing It All Together
For Azure AD, you need to use connect-AzureAD first to connect, and
for MS Online you can use Connect-MsolService. Once connected, you
will be able to use the following examples by updating the variables.
126
Chapter 10 Gluing It All Together
127
Chapter 10 Gluing It All Together
Method 2:
$a = import .\abc.csv
$a |ForEach-Object{
$Con_string = $null
$Con_string = $_.ID, $_.GrpName -join ','
Write-Host $Con_string
Add-Content .\abc6.csv $Con_string
}
128
Chapter 10 Gluing It All Together
14562
67578
65888
$filep = "c:\file.txt"
$getNetworkID = Get-Content $filep | where { $_ -ne "" }
@("Employeeid") + $getNetworkID | Set-Content $filep -Force
#add emplyeeidheader
R
egex
There are situations where you need to use regex for performing certain
match operations inside your scripts.
129
Chapter 10 Gluing It All Together
This is how you use it in PowerShell and it will be used mainly with
match operators. See Figures 10-6 and 10-7.
$regexemail = "^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"
"[email protected]" -match $regexemail
130
Chapter 10 Gluing It All Together
S
ummary
This is the last chapter of this book and it was all about how you can
combine different snippets and make a script that can do a bulk load of
work. I have shared different product examples that can be used by system
administrators in their daily work. More scripts and hundreds of examples
are available at https://techwizard.cloud/downloads/.
131
Index
A, B installation, 53
LaunchSPO, 57
Active Directory module
on-premise commands, 55
attributes, 111
on-premise server, 57
components, 109
password encryption
excel reporting, 111–117
active directory module, 64
exporting group members, 110
CSV file, 62
module, 118
get-auth source code, 60, 61
Quest management shell, 109,
Get-IniContent, 62, 63
110, 117
INI file, 62
remove members, 118, 119
PS credentials, 61
scripting, 109
random password, 63
Azure Active Directory (AD), 125
save-encrypted command,
administrators, 127
59, 60
checking process, 127
SharePoint online, 57
provisioning errors, 128
source code, 57, 58
remove option, 126
system admin functions, 54
user adding, 126
write-log function, 58, 59
Comma-separated values (CSV)
Compare-Object, 98
C reports, 77–80
Cheat module (vsadmin) Compare-Object
authentication prompt, 56 arrays, 94
commands, 54 cheat code, 94
features, 52 CSV files, 98
files, 53 remove operation, 95
Get-MailBox command, 56 synchronizing code, 96, 97
D I, J, K
Date/log files Import-CSV (comma-separated
folder structure, 21, 22 values)
formatting option, 18 array, 36
get-date command, 17 dot sourcing option, 34
log (see Log files) source code, 33
manipulation, 19, 20 text files, 35, 36
ready-made (see Ready-made Interactive input, 37
functions) read-host operation, 37–39
source code, 18 GUI button, 40–44
types, 17 parameters, 39
script execution, 39
Yes/No operation, 45–47
E, F, G
Email sending
formatted message L
body, 66, 67 Log files, Write-Log function, 27
HTML, 67–69
source code, 65
Error reporting, 71 M, N
email, 71 Microsoft exchange
error logging, 76 active sync stats, 106
log errors/text file, 75, 76 clean database, 105
send-email function, 72–74 disconnected mailboxes, 105
transcript logging, 74, 75 exchange quota
Excel reporting, 80–85 report, 107, 108
extract message, 106
message tracking, 106
H search mailbox/delete
Hypertext Markup Language messages, 107
(HTML), 67–69, 86–90 set quota, 109
134
Index
Modules variables, 4
cheat codes, 52 loops, 8
definition, 50 do-while, 12
gallery, 50 for loops, 9–12
list of, 52 foreach loop, 9
module path, 51 while, 12–14
products, 50 variable/printing, 2–4
upgrade option, 51 write-host variable, 3
O R
Office 365 Ready-made functions
mailbox report, 123, 124 set-recyclelogs function, 27–31
message tracking, 124 start-ProgressBar
unified audit logging, 125 function, 31, 32
vsadmin/separate functions, timeout cmdlet, 32
119–123 write-log function, 22–27
Regex, 129–131
Regular expression
P, Q testing, 130
split keyword, 91, 92 Replace operation, 93
PowerShell versions Reporting, 77
array illustration, 3 cheat code, 81
definition, 1 CSV
email sending, 65 execution result, 79
functions, 14–16 multiple sources, 78
if/else/switch multi-value attributes, 80
conditional/logical on-premise shell, 78
operators, 6 scripting code, 77
greater than operator, 4 transport logs, 80
-gt variable, 5 CSV-to-Excel conversion, 84
less than operator, 5 excel module, 80–85
logical operators, 7, 8 HTML dashboards, 85–90
-lt variable, 6 import-excel module, 85
135
Index
T, U
Text/CSV file operations, 128 V, W, X, Y, Z
Text file Vsadmin module, see Cheat
account names, 99 module (vsadmin)
136