137 58 6MB
English Pages 148 [144] Year 2021
PowerShell 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 ISBN-13 (pbk): 978-1-4842-7758-4 https://doi.org/10.1007/978-1-4842-7759-1
ISBN-13 (electronic): 978-1-4842-7759-1
Copyright © 2022 by Vikas Sukhija This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation, broadcasting, reproduction on microfilms or in any other physical way, and transmission or information storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now known or hereafter developed. Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark. The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to proprietary rights. While the advice and information in this book are believed to be true and accurate at the date of publication, neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or omissions that may be made. The publisher makes no warranty, express or implied, with respect to the material contained herein. Managing Director, Apress Media LLC: Welmoed Spahr Acquisitions Editor: Smriti Srivastava Development Editor: James Markham Coordinating Editor: Mark Powers Copy Editor: Mary Behr Cover designed by eStudioCalamar Cover image by Joshua Cotten on Unsplash (www.unsplash.com) Distributed to the book trade worldwide by Apress Media, LLC, 1 New York Plaza, New York, NY 10004, U.S.A. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail [email protected], or visit www.springeronline.com. Apress Media, LLC is a California LLC and the sole member (owner) is Springer Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc is a Delaware corporation. For information on translations, please e-mail [email protected]; for reprint, paperback, or audio rights, please e-mail [email protected]. Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales web page at www.apress.com/bulk-sales. Any source code or other supplementary material referenced by the author in this book is available to readers on GitHub via the book’s product page, located at www.apress.com/9781484277584. For more detailed information, please visit www.apress.com/source-code. Printed on acid-free paper
Table of Contents About the Author��������������������������������������������������������������������������������vii About the Technical Reviewer�������������������������������������������������������������ix Introduction�����������������������������������������������������������������������������������������xi Chapter 1: PowerShell Basics���������������������������������������������������������������1 Variables and Printing�������������������������������������������������������������������������������������������2 If/Else Switch��������������������������������������������������������������������������������������������������������4 Conditional/Logical Operators�������������������������������������������������������������������������6 Logical Operators��������������������������������������������������������������������������������������������7 Loops��������������������������������������������������������������������������������������������������������������������8 For Loop and While Loop���������������������������������������������������������������������������������������9 For Loop�����������������������������������������������������������������������������������������������������������9 While Loop�����������������������������������������������������������������������������������������������������12 Functions������������������������������������������������������������������������������������������������������������14 Summary������������������������������������������������������������������������������������������������������������16
Chapter 2: Date and Logs�������������������������������������������������������������������17 Date Manipulation�����������������������������������������������������������������������������������������������19 Creating Folders Based on a Date�����������������������������������������������������������������������21 Ready-Made Date and Log Functions�����������������������������������������������������������������22 Summary������������������������������������������������������������������������������������������������������������32
iii
Table of Contents
Chapter 3: Input to Your Scripts���������������������������������������������������������33 Import-CSV����������������������������������������������������������������������������������������������������������33 Importing from a Text File�����������������������������������������������������������������������������������35 Input from an Array���������������������������������������������������������������������������������������������36 Summary������������������������������������������������������������������������������������������������������������36
Chapter 4: Interactive Input����������������������������������������������������������������37 Read-host�����������������������������������������������������������������������������������������������������������37 Parameters���������������������������������������������������������������������������������������������������������39 GUI Button�����������������������������������������������������������������������������������������������������������40 Prompt (Yes or No)����������������������������������������������������������������������������������������������44 Summary������������������������������������������������������������������������������������������������������������46
Chapter 5: Adding Snapins/ Modules�������������������������������������������������47 PowerShell Snapins��������������������������������������������������������������������������������������������47 Modules��������������������������������������������������������������������������������������������������������������50 Cheat Module (vsadmin)�������������������������������������������������������������������������������������52 Encrypting a Password (vsadmin)�����������������������������������������������������������������59 Summary������������������������������������������������������������������������������������������������������������64
Chapter 6: Sending Email�������������������������������������������������������������������65 Formatting a Message Body�������������������������������������������������������������������������������66 Sending HTML�����������������������������������������������������������������������������������������������������67 Summary������������������������������������������������������������������������������������������������������������69
Chapter 7: Error Reporting�����������������������������������������������������������������71 Reporting Errors Through Email��������������������������������������������������������������������������71 Logging Everything Including Errors�������������������������������������������������������������������74 Logging Errors to a Text File��������������������������������������������������������������������������������75 Summary������������������������������������������������������������������������������������������������������������76 iv
Table of Contents
Chapter 8: Reporting��������������������������������������������������������������������������77 CSV Report����������������������������������������������������������������������������������������������������������77 Excel Reporting���������������������������������������������������������������������������������������������������80 HTML Reporting��������������������������������������������������������������������������������������������������85 Summary������������������������������������������������������������������������������������������������������������90
Chapter 9: Miscellaneous Keywords��������������������������������������������������91 Split���������������������������������������������������������������������������������������������������������������������91 Replace���������������������������������������������������������������������������������������������������������������92 Select-String�������������������������������������������������������������������������������������������������������93 Compare-Object��������������������������������������������������������������������������������������������������94 Summary������������������������������������������������������������������������������������������������������������98
Chapter 10: Gluing It All Together�������������������������������������������������������99 Product Examples (Daily Use)���������������������������������������������������������������������������105 Microsoft Exchange������������������������������������������������������������������������������������������105 Clean Database So That Mailboxes Appear in a Disconnected State����������105 Find Disconnected Mailboxes����������������������������������������������������������������������105 Extract Message Accept From���������������������������������������������������������������������106 Active Sync Stats�����������������������������������������������������������������������������������������106 Message Tracking����������������������������������������������������������������������������������������106 Search Mailbox/Delete Messages���������������������������������������������������������������107 Exchange Quota Report�������������������������������������������������������������������������������107 Set Quota�����������������������������������������������������������������������������������������������������109 Active Directory�������������������������������������������������������������������������������������������������109 Exporting Group Members���������������������������������������������������������������������������110 Setting Values for AD Attributes�������������������������������������������������������������������111 Exporting Active Directory Attributes�����������������������������������������������������������111
v
Table of Contents
Adding Members to the Group from a Text File�������������������������������������������117 Removing Members of the Group From a Text File��������������������������������������118 Office 365����������������������������������������������������������������������������������������������������������119 Exchange Online Mailbox Report�����������������������������������������������������������������123 Exchange Online Message Tracking������������������������������������������������������������124 Searching a Unified Log������������������������������������������������������������������������������125 Azure AD�����������������������������������������������������������������������������������������������������������125 Adding Users to an Azure AD Group From a Text File of UPN�����������������������126 Removing Users in an Azure AD Group from a Text File of UPN�������������������126 Checking If a User Is Already a Member of a Group������������������������������������127 Adding Administrators to a Role������������������������������������������������������������������127 Checking for Azure AD User Provisioning Errors������������������������������������������127 Text/CSV File Operations�����������������������������������������������������������������������������������128 Regex����������������������������������������������������������������������������������������������������������������129 Summary����������������������������������������������������������������������������������������������������������131
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).
© Vikas Sukhija 2022 V. Sukhija, PowerShell Fast Track, https://doi.org/10.1007/978-1-4842-7759-1_1
1
Chapter 1
PowerShell Basics
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" When you type $a and $b, values will be displayed, as shown in Figure 1-1.
Figure 1-1. Variables in PowerShell Now you can use Write-host to print this to the screen: Input: PS C:\> Write-host $a Output: 1 Input: PS C:\> Write-host $b Output: vikas
Tip Make it a rule to use quotes when assigning values to variables, as shown above in the two examples.
2
Chapter 1
PowerShell Basics
Let’s change the foreground color of what is being displayed by Write-host: Input: PS C:\> Write-host $b -ForegroundColor Green Output: vikas Input: PS C:\> Write-host "processing .........." -ForegroundColor Green Output: processing .......... PS C:\> Figure 1-2 shows the results.
Figure 1-2. Using the Write-host variable Let’s illustrate arrays quickly. In PowerShell, arrays can be defined in the same way as variables. Here are some examples: $b = "A","B","C","D","E" If you define it as a variable and separate the elements by a comma, PowerShell automatically understands that it is an array, as shown in Figure 1-3.
Figure 1-3. Array illustration 3
Chapter 1
PowerShell Basics
The proper way of defining an array is as follows because it is understood from the syntax itself that it is an array (as shown in Figure 1-4): $c= @("server1","server2")
Figure 1-4. Array syntax 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.
Listing 1-1. Example Code for Greater Than Operator Usage in If/Else [int]$a= "10"
4
Chapter 1
PowerShell Basics
if($a -gt "9") { write-host "True" -foregroundcolor Green }else { Write-host "False" -foregroundcolor Red } 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.
Figure 1-5. Showing -gt usage in if/else 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" if($a -lt "9"){ write-host "True" -foregroundcolor Green }else { Write-host "False" -foregroundcolor Red }
5
Chapter 1
PowerShell Basics
Figure 1-6. Showing -lt usage in if/else
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 -ne Not equal -ge Greater than or equal -gt Greater than -lt Less than -le Less than or equal -like
Wildcard comparison
-notlike
Wildcard comparison
-match
Regular expression comparison
-notmatch Regular expression comparison -replace
Replace operator
-contains Containment operator -notcontains Containment operator
6
Chapter 1
PowerShell Basics
L ogical Operators -and Logical AND -or Logical OR -not Logical NOT ! 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.
Listing 1-3. Example Code Showing Logical -or Operator [int]$a= "10" If(($a -lt "9") -or ($a -eq "10")){ write-host "True" -foregroundcolor Green }else { Write-host "False" -foregroundcolor Red}
Figure 1-7. Showing logical -or operator
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.
Listing 1-4. Code Showing Logical -and Operator [int]$a= "10" If(($a -lt "9") -and ($a -eq "10")){ write-host "True" -foregroundcolor Green }else { Write-host "False" -foregroundcolor Red}
Figure 1-8. Showing logical -and operator Not is for negation. I generally don’t use it often. In my experience, it causes human error if you are in hurry and do not think it through enough.
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
For Loop and While Loop F or Loop There are three iterations of for loops in PowerShell: •
foreach
•
foreach-object
•
for
Let’s differentiate between the three for loops by looking at the examples. foreach: You need to specify a foreach $variable in $collection: foreach ($i in $x).
Note You combine the if else and comparison operators in Listing 1-5. You can see the results in Figure 1-9. Listing 1-5. Code Showing a foreach Loop $x=@("1","2","3",,"4") foreach ($i in $x) { if ($i -lt 2) { write-host "$i is Green" -foregroundcolor Green } else{ write-host "$i is yellow" -foregroundcolor yellow } }
9
Chapter 1
PowerShell Basics
Figure 1-9. Showing a foreach loop foreach-object: You use a PIPE with the collection to achieve the same thing (see Listing 1-6 and Figure 1-10): $x | foreach-object
Listing 1-6. Code Showing a foreach-object Loop $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
Figure 1-10. Showing a foreach-object loop 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.
Listing 1-7. Code Showing a for Loop for($x=1; $x -le 5; $x++){ if($x -lt 2){write-host "$x is Green" -foregroundcolor Green } else{ write-host "$x is yellow" -foregroundcolor yellow } }
11
Chapter 1
PowerShell Basics
Figure 1-11. Showing a for loop
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
For do-while you do something until some condition is met. In Listing 1-8, variable x = 0 and inside the variable you increment its value until it is not equal to 4. See Figure 1-12 for the result.
Note You are doing the thing first and matching the condition later. Listing 1-8. Code Showing a do-while Loop $x= 0 Do {$x++
12
Chapter 1
PowerShell Basics
if($x -lt 2){write-host "$x is Green" -foregroundcolor Green } else{ write-host "$x is yellow" -foregroundcolor yellow } }while($x -ne 4)
Figure 1-12. Showing a do-while loop 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
Listing 1-9. Code Showing the while Loop $x= 0 while($x -ne 4) {$x++ if($x -lt 2){write-host "$x is Green" -foregroundcolor Green } else{ write-host "$x is yellow" -foregroundcolor yellow } }
Figure 1-13. Showing a while loop
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
Listing 1-10. Example Code Showing an Add Function of Two Numbers Function Add ($a1, $b1) { $a1 + $b1 } Add 5 6 # Call function
Figure 1-14. Showing an Add function of two numbers Similarly, you can create this for three or more numbers. See Listing 1-11 and Figure 1-15.
Listing 1-11. Example Code Showing an Add Function of Three Numbers Function Add ($a1, $b1, $c1) { $a1 + $b1 +$c1 } Add 5 6 9 # Call function
15
Chapter 1
PowerShell Basics
Figure 1-15. Showing an Add function of three numbers
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
Date and Logs To create scripts, it is essential to understand how to use the date and time cmdlet to timestamp different types of operations, such as creating a time- stamped log file. I will share a cheat function that you can utilize inside your scripts to create a time-stamped log as well as time-stamped entries inside the script. Let’s go through some date and time illustrations before utilizing the Write-Log function that I have already created for you. (This is the first actual cheat code that you will utilize in your scripts!) The get-date command provides you with the current date and time, as shown in Figure 2-1.
Figure 2-1. Showing the get-date cmdlet To format it in a manner that will allow it to be used in file names and other instances, the format keyword can be used as shown in Figure 2-2: get-date -format d
© Vikas Sukhija 2022 V. Sukhija, PowerShell Fast Track, https://doi.org/10.1007/978-1-4842-7759-1_2
17
Chapter 2
Date and Logs
Figure 2-2. Showing date formatting 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 $date $date $time $time $time
= = = = =
get-date -format d # formatting $date.ToString().Replace("/", "-") # replace / with get-date -format t # only show time $time.ToString().Replace(":", "-") # replace : with $time.ToString().Replace(" ", "")
$m = get-date $month = $m.month #getting month $year = $m.year #getting year Examples: - (now gluing them all together) #based on date $log1 = ".\Processed\Logs" + "\" + "skipcsv_" + $date + "_.log" #based on month and year $log2 = ".\Processed\Logs" + "\" + "Created_" + $month +"_" + $year +"_.log"
18
Chapter 2
Date and Logs
#based on date and time $output1 = ".\" + "G_Testlog_" + $date + "_" + $time + "_.csv"
Note Always define the current working folder.
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 $date= Get-Date -Day 01 $lastday = ((Get-Date -day 01).AddMonths(1)).AddDays(-1) $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
Creating Folders Based on a Date There can be situations in the real world in which you want to create folders based on the current date, such as making a SharePoint configuration backup every day and placing it in the date stamp folder. Listing 2-3 shows the code that can be utilized to do this task and Figure 2-5 shows the results.
Listing 2-3. Code for Creating a Folder Structure Based on a Date $Dname = ((get-date).AddDays(0).toString('yyyyMMdd')) #date manipulation $dirName = "ConfigBackup_$Dname" #prefix for the folder New-Item -Path c:\temp -Name $dirName -ItemType directory
21
Chapter 2
Date and Logs
Figure 2-5. Creating a folder structure based on a date
Ready-Made Date and Log Functions Here are three ready-made functions that you can copy and paste inside your scripts as per your requirements. Towards the end of this book, I will demonstrate how to create a complete script by using all the ready-made functions or code shared in this book. Write-Log function: It uses another function named New- FolderCreation, which can be used separately if required. See Listing 2-4.
22
Chapter 2
Date and Logs
Listing 2-4. Code for Write-Log Function 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
[Parameter(ParameterSetName = 'Create',Position = 0)] [switch]$Create, [Parameter(Mandatory = $true,ParameterSetName = 'Message')] [String]$message, [Parameter(Mandatory = $true,ParameterSetName = 'Message')] [String]$path, [Parameter(Mandatory = $false,ParameterSetName = 'Message')] [ValidateSet('Information','Warning','Error')] [string]$Severity = 'Information', [Parameter(ParameterSetName = 'Message',Position = 0)] [Switch]$MSG ) switch ($PsCmdlet.ParameterSetName) { "Create" { $log = @() $date1 = Get-Date -Format d $date1 = $date1.ToString().Replace("/", "-") $time = Get-Date -Format t $time = $time.ToString().Replace(":", "-") $time = $time.ToString().Replace(" ", "") New-FolderCreation -foldername $folder foreach ($n in $Name) {$log += (Get-Location).Path + "\" + $folder + "\" + $n + "_" + $date1 + "_" + $time + "_.$Ext"} return $log } "Message" { $date = Get-Date 24
Chapter 2
Date and Logs
$concatmessage = "|$date" + "| |" + $message +"| |" + "$Severity|" switch($Severity){ "Information"{Write-Host -Object $concatmessage -ForegroundColor Green} "Warning"{Write-Host -Object $concatmessage -ForegroundColor Yellow} "Error"{Write-Host -Object $concatmessage -ForegroundColor Red} } Add-Content -Path $path -Value $concatmessage } } } #Function Write-Log To create a log file, you can simply use it as below (it will auto-create the folders): $log = Write-Log -Name "Name-Log" -folder "logs" -Ext "log" To create a CSV file for report purposes, you can use it like so: $Report1 = Write-Log -Name "MAM-Report" -folder "Report" -Ext "csv" To write the information to a log file, you can use Write-log -Message "Connect to Intune" -path $log To write a warning to a log file, you can use Write-log -Message "Connect to Intune" -path $log -Severity Warning
25
Chapter 2
Date and Logs
To write an error to a log file, you can use Write-Log -Message "Error loading Modules" -path $log -Severity Error Figure 2-6 shows the Write-Log operation in the PowerShell console.
Figure 2-6. Write-Log operation 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 Set-Recyclelogs function: This will delete the files based on a number of days as input. As logs accumulate over time, there is a need to recycle them after a certain period to avoid filling up server drives. This is important for all scripts for which you have enabled logging. Use the code in Listing 2-5.
Listing 2-5. Code for the Set-Recyclelogs Function function Set-Recyclelogs { [CmdletBinding( SupportsShouldProcess = $true, ConfirmImpact = 'High')] param ( [Parameter(Mandatory = $true,ParameterSetName [string]$foldername, [Parameter(Mandatory = $true,ParameterSetName [Parameter(Mandatory = $true,ParameterSetName [Parameter(Mandatory = $true,ParameterSetName
= 'Local')] = 'Local')] = 'Path')] = 'Remote')] 27
Chapter 2
Date and Logs
[int]$limit, [Parameter(ParameterSetName = 'Local',Position = 0)] [switch]$local, [Parameter(Mandatory = $true,ParameterSetName = 'Remote')] [string]$ComputerName, [Parameter(Mandatory = $true,ParameterSetName = 'Remote')] [string]$DriveName, [Parameter(Mandatory = $true,ParameterSetName = 'Remote')] [string]$folderpath, [Parameter(ParameterSetName = 'Remote',Position = 0)] [switch]$Remote, [Parameter(Mandatory = $true,ParameterSetName = 'Path')] [ValidateScript({ if(-Not ($_ | Test-Path) ){throw "File or folder does not exist"} return $true })] [string]$folderlocation, [Parameter(ParameterSetName = 'Path',Position = 0)] [switch]$Path ) 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: Set-Recyclelogs -foldername logs -limit 10 Use confirm:$false to avoid confirmation once you are sure that you want to delete the files: Set-Recyclelogs -foldername logs -limit 10 -confirm:$false Use verbose to check which files are getting deleted: Set-Recyclelogs -foldername logs -limit 10 -confirm:$false -verbose
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: Set-Recyclelogs -folderlocation c:\temp\logs -limit 10 To recycle logs on a remote machine, use the following syntax: Set-Recyclelogs -ComputerName testmachine -DriveName c -folderpath data\logs -limit 10 Set-ProgressBar function: This function is just to show the progress bar when you want to pause for some time. See Listing 2-6 and Figure 2-8.
Listing 2-6. Code for Start-ProgressBar Function function Start-ProgressBar { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] $Title, [Parameter(Mandatory = $true)] [int]$Timer ) For ($i = 1; $i -le $Timer; $i++) { Start-Sleep -Seconds 1; Write-Progress -Activity $Title -Status "$i" -Percent Complete ($i /100 * 100) } } #Function Start-ProgressBar Start-ProgressBar -Title “Test timeout” -Timer 30
31
Chapter 2
Date and Logs
Figure 2-8. Start-ProgressBar with a timer of 30 seconds You can use a simple timeout as well, which is built in (see Figure 2-9): timeout 10
Figure 2-9. Built-in timeout cmdlet
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
Input to Your Scripts There are many situations in the practical system administration world in which you have to feed your scripts with inputs. Examples are reading a text file that has a list of users and adding them to a specific Active Directory group, or reading a CSV file that includes user attributes like phone number, title, and department, and updating these attributes in Active Directory. In this chapter, you will look at the different ways of feeding your scripts with different types of inputs.
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.
Figure 3-1. Example CSV file
© Vikas Sukhija 2022 V. Sukhija, PowerShell Fast Track, https://doi.org/10.1007/978-1-4842-7759-1_3
33
Chapter 3
Input to Your Scripts
Listing 3-1. Code for Import-CSV $data = import-csv c:\temp\samplecsv.csv #Import CSV in variable data foreach ($i in $data) { Write-host $i.user -foregroundcolor green #printing column user Write-host $i.email -foregroundcolor yellow #printing column email Write-host $i.title -foregroundcolor magenta #printing column title } Figure 3-2 shows the Import-CSV operation in PowerShell. If you are in the same folder, you can use dot source instead of the full path shown in screenshot: $data = import-csv .\samplecsv.csv # .\ means current directory
Figure 3-2. Showing the Import-CSV operation by dot sourcing (.\)
34
Chapter 3
Input to Your Scripts
Importing from a Text File There are scenarios in which you get data in a text file, such as a server list or a user list, one name at a time, and you want to perform a certain operation on the data. Figure 3-3 shows the printing of each server from a file named servers.txt file onto the screen. (Get-content is the cmdlet used for reading text files; see Listing 3-2.)
Figure 3-3. Example text file contents Listing 3-2. Code for Reading from a Text File $servers = Get-content .\servers.txt $servers | foreach-object { Write-host $_ } Save the code in a .ps1 file and run it or just paste it in the PowerShell console. See Figure 3-4.
Figure 3-4. Reading from a text file operation in PowerShell 35
Chapter 3
Input to Your Scripts
I nput from an Array You can do the same thing with array that you have done with text file. Say you have array of servers and you want to print it on the screen. See Listing 3-3.
Listing 3-3. Code for Reading from an Array and Printing It $servers = @("server01","server02","server03","server04") #array of servers $servers | foreach-object { Write-host $_ -foregroundcolor yellow } Running this script will show the results in Figure 3-5.
Figure 3-5. Showing the printing of an array
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: $x =Read-host "input your Name" The value of your input is saved in an $x variable so you can use it in the script for further processing, as shown in Figure 4-1.
Figure 4-1. Read-host operation
© Vikas Sukhija 2022 V. Sukhija, PowerShell Fast Track, https://doi.org/10.1007/978-1-4842-7759-1_4
37
Chapter 4
Interactive Input
Another option is to specifically use the -prompt parameter. There is no difference in how you use it. See Figure 4-2. $Age =Read-host -prompt "input your Age."
Figure 4-3. Read-host operation for a password as an input -assecurestring is used when you want to input a password securely: $Password = Read-Host -assecurestring "Enter your password" Here as well the value of the password entered is saved in the $Password variable that you can use it in the script for further processing, such as authentication to some service like Office 365. See Figure 4-3.
Figure 4-2. Read-host operation specifying the -prompt
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.
Listing 4-1. Example Code Showing Use of Parameters Param( [string]$firstname, [string]$lastname, [string]$title ) Write-host "First Name: $firstname" -ForegroundColor Yellow Write-host "Last Name: $lastname" -ForegroundColor Yellow Write-host "Title: $Title" -ForegroundColor green Save this as a .ps1 file and run it as follows (and see Figure 4-4): .\script.ps1 -firstname Vikas -lastname sukhija -title blogger
Figure 4-4. Script execution with parameters
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.
Listing 4-2. Code for Input from a GUI Button function button ($title,$mailbx, $WF, $TF) { ###################Load Assembly for creating form & button###### [void][System.Reflection.Assembly]::LoadWithPartialName( "System.Windows.Forms") [void][System.Reflection.Assembly]::LoadWithPartialName( "Microsoft.VisualBasic") #####Define the form size & placement $form = New-Object "System.Windows.Forms.Form"; $form.Width = 500; $form.Height = 150; $form.Text = $title; $form.StartPosition = [System.Windows.Forms.FormStartPosition ]::CenterScreen; ##############Define text label1 $textLabel1 = New-Object "System.Windows.Forms.Label"; $textLabel1.Left = 25; $textLabel1.Top = 15; $textLabel1.Text = $mailbx;
40
Chapter 4
Interactive Input
##############Define text label2 $textLabel2 = New-Object "System.Windows.Forms.Label"; $textLabel2.Left = 25; $textLabel2.Top = 50; $textLabel2.Text = $WF; ##############Define text label3 $textLabel3 = New-Object "System.Windows.Forms.Label"; $textLabel3.Left = 25; $textLabel3.Top = 85; $textLabel3.Text = $TF; ############Define text box1 for input $textBox1 = New-Object "System.Windows.Forms.TextBox"; $textBox1.Left = 150; $textBox1.Top = 10; $textBox1.width = 200; ############Define text box2 for input $textBox2 = New-Object "System.Windows.Forms.TextBox"; $textBox2.Left = 150; $textBox2.Top = 50; $textBox2.width = 200; ############Define text box3 for input $textBox3 = New-Object "System.Windows.Forms.TextBox"; $textBox3.Left = 150; $textBox3.Top = 90; $textBox3.width = 200;
41
Chapter 4
Interactive Input
#############Define default values for the input boxes $defaultValue = "" $textBox1.Text = $defaultValue; $textBox2.Text = $defaultValue; $textBox3.Text = $defaultValue; #############define OK button $button = New-Object "System.Windows.Forms.Button"; $button.Left = 360; $button.Top = 85; $button.Width = 100; $button.Text = "Ok"; ############# This is when you have to close the form after getting values $eventHandler = [System.EventHandler]{ $textBox1.Text; $textBox2.Text; $textBox3.Text; $form.Close(); }; $button.Add_Click($eventHandler) ; #############Add controls to all the above objects defined $form.Controls.Add($button); $form.Controls.Add($textLabel1); $form.Controls.Add($textLabel2); $form.Controls.Add($textLabel3); $form.Controls.Add($textBox1); $form.Controls.Add($textBox2); $form.Controls.Add($textBox3); $ret = $form.ShowDialog();
42
Chapter 4
Interactive Input
#################return values return $textBox1.Text, $textBox2.Text, $textBox3.Text } #button Load this function into your script, and then you can perform the operations on the inputs as shown: $return= button "Enter Folders" "Enter mailbox" "Working Folder" "Target Folder" You can choose different names per your requirements. See Figure 4-5.
Figure 4-5. GUI button input After you press the OK button, the $return variable contains all these values in the array (see Figure 4-6): $return[0] → Enter mailbox value $return[1] → Working folder value $return[2] → Target Folder value
43
Chapter 4
Interactive Input
Figure 4-6. Showing values returned from the user input You can also print to the screen in the same manner as shown previously (see Figure 4-7): Write-host "Enter mailbox : $($return[0])" -ForegroundColor Yellow Write-host "Working folder : $($return[1])" -ForegroundColor Yellow Write-host "Target Folder : $($return[2])" -ForegroundColor green
Figure 4-7. Printing the values from the input using Write-host
Prompt (Yes or No) There are practical situations when as a system administrator you want to build a nice way to get a Yes/No response from the users. You can do this easily with PowerShell utilizing the cheat code in Listing 4-3.
44
Chapter 4
Interactive Input
Listing 4-3. Code for a Yes/No Operation $overwrite = New-Object -comobject wscript.shell $Answer = $overwrite.popup("Do you want to Overwrite AD Attributes?",0,"Overwrite Attributes",4) If ($Answer -eq 6) {Write-Host "you pressed Yes" -ForegroundColor Green} else{Write-Host "you pressed Yes" -ForegroundColor Red} Copy and paste the code into the PowerShell console or save the script as a .ps1 file and run it. See Figure 4-8.
Figure 4-8. Showing a Yes/No operation in PowerShell If you press Yes, you get the result shown in Figure 4-9.
45
Chapter 4
Interactive Input
Figure 4-9. Showing the Yes operation If you press No, you get the result shown in Figure 4-10.
Figure 4-10. Showing the No operation Instead of just Write-host you can perform different operations inside your script based on the response selected by the user.
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).
© Vikas Sukhija 2022 V. Sukhija, PowerShell Fast Track, https://doi.org/10.1007/978-1-4842-7759-1_5
47
Chapter 5
Adding Snapins/ Modules
Note Exchange management binaries should be installed first on the machine or the snapin will not work. Listing 5-1. Code to Add the Exchange 2007 Management Shell If ((Get-PSSnapin | where {$_.Name -match "Exchange. Management"}) -eq $null) { Add-PSSnapin Microsoft.Exchange.Management.PowerShell. Admin }
Listing 5-2. Code to Add the Exchange 2010 Management Shell If ((Get-PSSnapin | Where-Object { $_.Name -match "Microsoft. Exchange.Management.PowerShell.E2010" }) -eq $null) { Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 } 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.
Figure 5-1. Exchange Management Shell
48
Chapter 5
Adding Snapins/ Modules
You can also use get-pssnapin in the PowerShell shell window to check which snapin is available. In Figure 5-2, I want to take advantage of the Quest shell, so I use get- pssnapin in the Quest AD shell to find out the snapin name.
Figure 5-2. Quest AD Management Shell Listing 5-3 shows how to add the snapin to the PowerShell script or session using the same technique as for the Exchange product.
Listing 5-3. Code to Add the Quest AD Management Shell If ((Get-PSSnapin | where {$_.Name -match "Quest.ActiveRoles"}) -eq $null) { Add-PSSnapin Quest.ActiveRoles.ADManagement }
Note The above code to add a snapin first checks to see if the snapin already exists. If so, it does nothing. If not, it adds the required snapin.
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: Install-Module -Name AzureAD Enter yes (as shown in Figure 5-3) when you receive the prompt to install the module.
Figure 5-3. Installing a module from PowerShell Gallery 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
Figure 5-4. Module path on the computer There may be a situation where a developer has developed a new version of the module and you want to update your machine with this newer version. Use one of the following commands to upgrade the existing module: Update-Module -Name AzureAD or Install-Module -Name AzureAD -force (this will also upgrade the module to latest version) With update you can also update the module to a specific version: Update-Module -Name AzureAD -RequiredVersion 1.0.1 Removing the module is a simple operation and can be done as shown in the following cmdlet: 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.
Note After PowerShell V3, modules are loaded automatically when the first cmdlet from that module is run from the script. 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
Figure 5-5. Showing a list of available modules on the computer
Cheat Module (vsadmin) Since this book is about cheat codes to create complex scripts, here is a cheat module that is full of functions that you can utilize to do complex operations inside your scripts. I recently created this module for the community to help them with scripting. I update it to newer versions from time to time as features change for different products. Module name: vsadmin Installing the module (see Figure 5-6): Install-Module -Name vsadmin
52
Chapter 5
Adding Snapins/ Modules
Figure 5-6. Installing the vsadmin module Once installed, you will find files created inside your module’s directory (C:\Program Files\WindowsPowerShell\Modules) as depicted in Figure 5-7.
Figure 5-7. Showing files inside the vsadmin module 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: Get-Command -Module vsadmin
53
Chapter 5
Adding Snapins/ Modules
Figure 5-8. Available vsadmin module commands Let’s explore Office 365 functions and then we will move on to other system admin functions that you can utilize daily.
54
•
LaunchEOL/RemoveEOL (Exchange Online)
•
LaunchSOL/RemoveSOL (Skype online)
•
LaunchSPO/RemoveSPO (SharePoint online)
•
LaunchCOL/RemoveCOL (Security and Compliance)
•
LaunchMSOL/RemoveMSOL (MSonline Azure Active Directory)
•
LaunchEXOnprem/RemoveEXOnprem (for on-premise Exchange Server)
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
•
Sharepoint Online, www.microsoft.com/en-ca/ download/details.aspx?id=35588
•
MSOnline Module, www.powershellgallery.com/ packages/MSOnline
•
Skype Online (Retired) All cmdlets are under the Teams Module at www.powershellgallery.com/ packages/MicrosoftTeams
For example, you can use LaunchEOL if you just want to connect to Office 365 Exchange online. It will prompt you for authentication and, once authenticated, you will get connected. It will check if the Exchange Online Management Shell is installed on your computer or not. If not, it will provide you with a hint. See Figure 5-9.
55
Chapter 5
Adding Snapins/ Modules
Figure 5-9. Authentication prompt by Office 365 Figure 5-10 shows that you are connected and can use the Exchange commands.
Figure 5-10. Exchange Online Management Shell prefixed Get-MailBox command
56
Chapter 5
Adding Snapins/ Modules
If you want to use these commands in a script without entering a password every time (a technique you will learn after finishing this book), LaunchEOL -Credential can be used by passing PS credentials. Similarly, you can use other functions because they are designed in a similar manner. For example, use this code and see the results in Figure 5-11: LaunchSPO –orgName techwizard
Figure 5-11. Showing a connection to SharePoint Online using LaunchSPO
Tip Pressing Tab on a keyboard after pressing the hyphen will show you the parameters available for any function in PowerShell. To disconnect the session, you can use the following functions: 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: LaunchEXOnprem -psurl http://exchangeserver.techwizard.cloud/ Powershell or LaunchEXOnprem -ComputerName exchangeserver.techwizard.cloud 57
Chapter 5
Adding Snapins/ Modules
To disconnect, use the same technique you used for Office 365 functions: RemoveEXOnprem -computername exchangeserver.techwizard.cloud Let’s now discuss generic functions inside this module. In Chapter 2, Write-Log, Set-recyclelogs, start-progressbar and other cheat function were shared. These functions are part of this module as well, so you do not have to copy and paste them in your scripts if you are importing this module in the script. See Listing 5-4 and Figure 5-12.
Listing 5-4. Importing vsadmin and Using the Write-Log Function Import-Module vsadmin $log = Write-Log -Name "log_file" -folder logs -Ext log Write-Log -Message "Information..........Script" -path $log #default will log as information Write-Log -Message "warning.........Message" -path $log -Severity Warning #you can display warning using the severity Write-Log -Message "error.........Error" -path $log -Severity error #you can display error using the severity
58
Chapter 5
Adding Snapins/ Modules
Figure 5-12. Showing the result of executing Listing 5-4 In a similar fashion, you can create a CSV file: $report = Write-Log -Name "log_Enable" -folder reports -Ext csv 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.
Encrypting a Password (vsadmin) You can encrypt a password and later utilize in it the script to connect to online services like Office 365 and Azure as follows (see Figure 5-13 for the result): Save-EncryptedPassword -password "testpassword" -path c:\temp\ password1.txt 59
Chapter 5
Adding Snapins/ Modules
Figure 5-13. Encrypting a password using the save-encrypted command get-auth is another important function that you can use in your scripts to read credentials from the encrypted text file that you created above. You use it as follows: $cred = get-auth -userId [email protected] -passwordfile c:\temp\password1.txt $pwd = $cred[0] ### credentials that can be used inside csom / api calls. $pscredential = $cred[1] ###credentials that can be used for functions that supports ps credentials. or $cred = get-auth -userId [email protected] -password "encryptedpassword" $pwd = $cred[0] ### credentials that can be used inside csom / api calls. 60
Chapter 5
Adding Snapins/ Modules
$pscredential = $cred[1] ###credentials that can be used for functions that supports ps credentials. 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.
Listing 5-5. Code Showing Use of PS Credentials Import-Module vsadmin $cred = get-auth -userId [email protected] -passwordfile "c:\temp\password1.txt" #getcredentials that you created using Save-EncryptedPassword $pscredential = $cred[1] ###credentials that can be used for functions that supports ps credentials. LaunchEOL -Credential $pscredential $data = Get-EOLMailbox -ResultSize unlimited | Select Name,Wind owsEmailAddress,IssueWarningQuota, ProhibitSendQuota,ProhibitSe ndReceiveQuota #fetch the required data from exchange online $data | Export-Csv "c:\temp\mailboxes.csv" -NoTypeInformation #export the data in csv format RemoveEOL #disconnect the exchange online session
61
Chapter 5
Adding Snapins/ Modules
Figure 5-14. Exporting the mailboxes data in a CSV file Use Get-IniContent to read ini files and then use the values in scripts. See Figure 5-15.
Figure 5-15. Example INI file You can see an example of the following code in Figure 5-16: $inifile = "c:\temp\config.ini" $readini = Get-IniContent $inifile $User = $readini["ServiceAccount"].UserID
62
Chapter 5
Adding Snapins/ Modules
Figure 5-16. Showing how to read an INI file using Get-IniContent Another useful day-to-day function is Save-CSV2Excel. As the name suggests, it converts a CSV file to formatted Excel: Save-CSV2Excel -CSVPath C:\data\auditmbx.csv -Exceloutputpath c:\data\audit.xlsx Random complex passwords are essential in the system administrator world. So why use the Web or a tool to generate them when you can do so with the New-RandomPassword function from the vsadmin module? See this example in Figure 5-17: New-RandomPassword – NumberofChars 9 It has been coded with 5, 9 ,14, and 20.
Figure 5-17. Showing the generation of a random password 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: Get-ADGroupMembersRecursive -Groups "Test Nested Group" You can read more about this function at https://techwizard. cloud/2020/10/24/get-ad-group-members-recursively/. Get-ADUserMemberOf can check if a user is a member of a group or not, but the AD module is required: Get-ADUserMemberOf -User "User" -Group "Group" It returns true if the user is a member of a group or else it returns false. You can read more about this function at https://techwizard. cloud/2020/12/31/check-if-ad-user-is-member-of-group/.
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: Send-MailMessage -SmtpServer "smtpserver" -From "DoNotReply@ labtest.com" -To "[email protected] " -Subject "Error exception occured " -Body "body of the message" 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.
Listing 6-1. Sending a Message with Powershell v1 $smtpserver = "smtp.lab.com" $to = "[email protected]" $from = "[email protected]" $file = "c:\file.txt" #for attachment $subject = "Test Subject" $message = new-object Net.Mail.MailMessage $smtp = new-object Net.Mail.SmtpClient($smtpserver) $message.From = $from
© Vikas Sukhija 2022 V. Sukhija, PowerShell Fast Track, https://doi.org/10.1007/978-1-4842-7759-1_6
65
Chapter 6
Sending Email
$message.To.Add($to) $att = new-object Net.Mail.Attachment($file) $message.IsBodyHtml = $False $message.Subject = $subject $message.Attachments.Add($att) $smtp.Send($message)
Formatting a Message Body There are situations in which you want to send a properly formatted email body instead of just a one-liner email. You can use the cheat code in Listing 6-2 for this purpose. You can see the result in Figure 6-1.
Listing 6-2. Sending a Formatted Message Body $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
Figure 6-1. The result of Listing 6-2
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
Figure 6-2. The HTML Online Editor Create some HTML content and use the code in Listing 6-3. You can see the result in Figure 6-3.
Listing 6-3. Sending HTML-Formatted Email $smtpserver = "smtp.lab.com" $to = "[email protected]" $from = "[email protected]" $subject = "Test Subject" $message = @" " add-content $report "" Add-Content $report "" Add-Content $report "" add-content $report "
" add-content $report "DAG Active Manager" add-content $report " | " add-content $report "
Identity | "PrimaryA ctiveManager | " Add-Content $report "Operati onalMachines | " Add-Content $report "||||
" add-content $report "DAG Database Backup Status" add-content $report " | " add-content $report "
Database | " Add-Content $report "BackupIn Progress | " Add-Content $report "Snapsho tLastFullBackup | " Add-Content $report "Snapshot LastCopyBackup | " Add-Content $report "LastFul lBackup | " Add-Content $report "RetainDe letedItemsUntilBackup | "|
$dbname | " Add-Content $report "$dbbkprg | " Add-Content $report "$dbsnpl | " Add-Content $report "$dbsnplc | " if($dblfb -lt $hrs) { Add-Content $report "$dblfb | " } else { Add-Content $report "$dblfb | " } Add-Content $report "$dbrd | "