All posts by Thiyagu

How to create Basic Chart by reading excel using PowerShell

As system admins, we are used to digging through heaps of searching, selecting, sorting, filtering, until we got what we were looking for. My point is, while you might appreciate nicely presented, If we are providing the technical details in paragraph format will usually get bored and things they don’t understand, this what we will do at most of the time. Most of the management peoples like simple and colorful representation like charts. Basically it will be easily understandable without reading long texts.

Below code is pretty basic and there are couple of things which is taken by default like Chart Type (which is Bar chart), Data range used for chart (Since single data set is present), position of the chart etc. Before executing the script, we need the data in a tabular format which is to be used to create a chart in the Excel. Let you create the excel sheet similar like below before we moving to the scripting part.

First let you Open the excel and add a chart details in the sheet as shown below. If required Set the Title and the Save the excel. Finally close the excel.

Full Code :

#######################################################################
#Project : How to create Basic Chart by reading excel using PowerShell
#Developer : Thiyagu S (dotnet-helpers.com)
#Tools : PowerShell 5.1.15063.1155 
#E-Mail : mail2thiyaguji@gmail.com 
######################################################################

# Creating excel com object
$xlChart=[Microsoft.Office.Interop.Excel.XLChartType]

#You can use New-Object to work with Component Object Model (COM) components.
#To create a COM object, you need to specify the ComObject parameter with the Programmatic Identifier of the COM class that you want to use
$excelObj = New-object -ComObject Excel.Application 

#Assign the the file path of the Excel
$fileName = 'C:\dotnet-helpers\TutorialDetails.xlsx'

#Open Excel
$workbook = $excelObj.Workbooks.Open($fileName)

#Open the first sheet of the excel 
$worksheetChart = $workbook.WorkSheets.item(1) 

#Makes the current sheet the active sheet.
$worksheetChart.activate() 

# Adding the Chart
$basicchart = $worksheetChart.Shapes.AddChart().Chart

# Set it true if you want to have chart Title
$basicchart.HasTitle = $true

# Assigning the Title for the chart
$basicchart.ChartTitle.Text = "Tutorial Views Report"

# Save the sheet
$workbook.Save()  

# Closing the work book and ComObject
$workbook.close() 
$excelObj.Quit()
# Releasting the excel com object
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excelObj)

OUTPUT

How to use splatting in Powershell – Part I

Splatting is a method of passing a collection of parameter values to a command as unit. PowerShell associates each value in the collection with a command parameter. Splatted parameter values are stored in named splatting variables, which look like standard variables, but begin with an At symbol (@) instead of a dollar sign ($). The At symbol tells PowerShell that you are passing a collection of values, instead of a single value.

Splatting is the ability to use a dictionary or a list to supply parameters to a command. Proxy commands are wrappers of existing commands in Windows PowerShell, and to make this possible.Instead of having to stretch your parameter assignments out horizontally, Splatting gives us a clean, concise, readable format that extends vertically in which to assign values to our parameters.

PROS of Splatting:

  • Splatting makes your commands shorter and easier to read.
  • You can re-use the splatting values in different command calls and use splatting to pass parameter values from the $PSBoundParameters automatic variable to other scripts and functions.

SYNTAX

<CommandName> <optional parameters> @<HashTable> <optional parameters>
<CommandName> <optional parameters> @<Array> <optional parameters>

Example 1: Splatting with Array

In this examples compare two Copy-Item commands that copy the txt file to the txt file in the same directory. For better understanding,
first let we see the example uses the traditional format which we usually use all the time.

Copy-Item -Path ‘C:\blog\source.txt’ ‘C:\blog\desination.txt’

In next let we create simple example and will use array splatting.
The first command creates an array of the parameter values and stores it in the $splattingArray variable.The values are in position order in the array.
The second command uses the @splattingArray variable in a command in splatting and you can notice that the $ symbol replaces the dollar sign (@splattingArray) in the command.

$splattingArray = “C:\blog\source.txt”, C:\blog\desination.txt”
Copy-Item -Path @splattingArray

Example 2: Splatting with Hash table

In this example we uses hash table splatting. The first command creates a hash table with key-value pairs and stores it in the $splattingHash variable.
The second command uses the $splattingHash variable in a command with splatting. and you can notice that the $ symbol replaces the dollar sign ($splattingHash) in the command.

$splattingHash = @{
  Path = "C:\blog\source.txt"
  Destination = "C:\blog\desination.txt"
}
Copy-Item @splattingHash

 

#Define the hash table            
$splattingGWMIParams = @{            
    Class = "Win32_OperatingSystem"            
    Credential = $Cred            
    ComputerName = 'localhost'            
}            
            
#Splat the hash table           
Get-WmiObject @splattingGWMIParams

 

What do you think?

I hope you have an idea of  How to use splatting in Powershell Scriptingl. I would like to have feedback from my posts readers. Your valuable feedback, question, or comments about this article are always welcome.

Creating Chart Reports using Powershell Chart controls

As system admins, we are used to digging through heaps of searching, selecting, sorting, filtering, until we got what we were looking for. My point is, while you might appreciate nicely presented, If we are providing the technical details in paragraph format will usually get bored and things they don’t understand, this what we will do most of the time. Most of the management peoples like simple and colorful representations like charts. Basically, it will be easily understandable without reading long texts.

Microsoft Chart Controls (MCCs) is a great tool to show up reports and you can create a wide range of different chart types, with a custom design. You can display your chart in a GUI (e.g. Windows Forms) or save it as a graphics file to include it in an HTML report or email. A standard chart created with MCCs basically consists of three elements that are Chart object, a ChartArea object, and one or more data Series.

From MSDN, Two important properties of the Chart class are the Series and ChartAreas properties, both of which are collection properties. The Series collection property stores Series objects, which are used to store data that is to be displayed, along with attributes of that data. The ChartAreas collection property stores ChartArea objects, which are primarily used to draw one or more charts using one set of axes.

How to create a simple Memory Usage Chart and save it in your local drive: In this post, we will create a chart that shows your pc’s top 5 processes by memory usage and save it as a *.png-file.

STEP #1

Let you loading the necessary assembly and determine the path whether the PNG need to save.

[void][Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms.DataVisualization”)
$chartSavePath = ‘C:\MonitorCPUusage’

STEP #2

In this example we won’t display this one in a GUI so you only need to set a few properties like black color and size. Here we going to create instance of the .NET-object we’ve just created and named “$chartobject” and set the Width, Height, back color. The System.Windows.Forms.DataVisualization.Charting namespace contains methods and properties for the Chart Windows forms control.

# Creating chart object
$chartobject = New-object System.Windows.Forms.DataVisualization.Charting.Chart
$chartobject.Width = 800
$chartobject.Height =800
$chartobject.BackColor = [System.Drawing.Color]::orange

STEP #3

Next, you need to add a title to the chart. A Chart object can have multiple titles (e.g. a title and a subtitle, or a title for each ChartArea attached to this Chart object), so we create it by adding it with title collection.

# Set Chart title
[void]$chartobject.Titles.Add(“dotnet-helpers chart-Memory Usage”)
$chartobject.Titles[0].Font = “Arial,13pt”
$chartobject.Titles[0].Alignment = “topLeft”

STEP #4

As mentioned before, a Chart object can have multiple ChartArea objects. Per default, they will automatically share the available space of the Chart object (determined by the Chart object’s height and width properties). But you can also customize the location and size of each ChartArea by setting the “$ChartArea.Position.Auto” – property to $false and set size and position yourself

# create a chartarea to draw on and add to chart
$chartareaobject = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
$chartareaobject.Name = “ChartArea1”
$chartareaobject.AxisY.Title = “dotnet-helpers chart – Memory(MB)”
$chartareaobject.AxisX.Title = “dotnet-helpers chart – Process Name”
$chartareaobject.AxisY.Interval = 100
$chartareaobject.AxisX.Interval = 1
$chartobject.ChartAreas.Add($chartareaobject)

STEP #5

Typically, if you want to add a legend along with a chart,I will avoid having anything on the actual chart itself and leave the description for each piece to be in the legend. Because we’ll have two data Series in the same ChartArea and it’s probably a good idea to be represent in the legend way.

# Creating legend for the chart
$chartlegend = New-Object system.Windows.Forms.DataVisualization.Charting.Legend
$legend.name = “Legend1”
$chartobject.Legends.Add($legend)

STEP #6

Here we getting the using process details by get-process cmdlet, sort by private memory size and take the top five entries of the list.

# Getting the top 5 CPU utilzation process details
$topCPUUtilization = Get-Process | sort PrivateMemorySize -Descending | Select-Object -First 5

STEP #7

Finally, we need to set the data series to chart object. We create it by setting a name for the Series and adding it directly to the chart’s Series collection. For this example, i had set the chart type to column. When choosing the type, there is one important thing to consider: You know already that a ChartArea can have multiple Series.

# Set Series to CharObject
[void]$chartobject.Series.Add(“VirtualMemory”)
$chartobject.Series[“VirtualMemory”].ChartType = “Column”
$chartobject.Series[“VirtualMemory”].BorderWidth = 3
$chartobject.Series[“VirtualMemory”].IsVisibleInLegend = $true
$chartobject.Series[“VirtualMemory”].chartarea = “ChartArea1”
$chartobject.Series[“VirtualMemory”].Legend = “Legend1”
$chartobject.Series[“VirtualMemory”].color = “#62B5CC”
$topCPUUtilization | ForEach-Object {$chartobject.Series[“VirtualMemory”].Points.addxy( $_.Name , ($_.VirtualMemorySize / 1000000)) }

# Set Series to CharObject
[void]$chartobject.Series.Add(“PrivateMemory”)
$chartobject.Series[“PrivateMemory”].ChartType = “Column”
$chartobject.Series[“PrivateMemory”].IsVisibleInLegend = $true
$chartobject.Series[“PrivateMemory”].BorderWidth = 3
$chartobject.Series[“PrivateMemory”].chartarea = “ChartArea1”
$chartobject.Series[“PrivateMemory”].Legend = “Legend1”
$chartobject.Series[“PrivateMemory”].color = “#E3B64C”
$topCPUUtilization | ForEach-Object {$chartobject.Series[“PrivateMemory”].Points.addxy( $_.Name , ($_.PrivateMemorySize / 1000000)) }

STEP #8

At last, you want to save chart as a image file using the .saveImage() method of the Chart object.

# save chart with the Time frame
$chartobject.SaveImage(“$chartSavePath\CPUusage_$(get-date -format `”yyyyMMdd_hhmmsstt`”).png”,”png”)

Full Code

[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")
$chartSavePath = 'C:\MonitorCPUusage'
 
# Creating chart object
# The System.Windows.Forms.DataVisualization.Charting namespace contains methods and properties for the Chart Windows forms control.
   $chartobject = New-object System.Windows.Forms.DataVisualization.Charting.Chart
   $chartobject.Width = 800
   $chartobject.Height =800
   $chartobject.BackColor = [System.Drawing.Color]::orange
 
# Set Chart title 
   [void]$chartobject.Titles.Add("dotnet-helpers chart-Memory Usage")
   $chartobject.Titles[0].Font = "Arial,13pt"
   $chartobject.Titles[0].Alignment = "topLeft"
 
# create a chartarea to draw on and add to chart
   $chartareaobject = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
   $chartareaobject.Name = "ChartArea1"
   $chartareaobject.AxisY.Title = "dotnet-helpers chart - Memory"
   $chartareaobject.AxisX.Title = "dotnet-helpers chart - ProcessName"
   $chartareaobject.AxisY.Interval = 100
   $chartareaobject.AxisX.Interval = 1
   $chartobject.ChartAreas.Add($chartareaobject)
 
# Creating legend for the chart
   $chartlegend = New-Object system.Windows.Forms.DataVisualization.Charting.Legend
   $legend.name = "Legend1"
   $chartobject.Legends.Add($legend)
 
# Get the top 5 process using in our system
   $topCPUUtilization = Get-Process | sort PrivateMemorySize -Descending  | Select-Object -First 5
 
# data series
   [void]$chartobject.Series.Add("VirtualMemory")
   $chartobject.Series["VirtualMemory"].ChartType = "Column"
   $chartobject.Series["VirtualMemory"].BorderWidth  = 3
   $chartobject.Series["VirtualMemory"].IsVisibleInLegend = $true
   $chartobject.Series["VirtualMemory"].chartarea = "ChartArea1"
   $chartobject.Series["VirtualMemory"].Legend = "Legend1"
   $chartobject.Series["VirtualMemory"].color = "#00bfff"
   $topCPUUtilization | ForEach-Object {$chartobject.Series["VirtualMemory"].Points.addxy( $_.Name , ($_.VirtualMemorySize / 1000000)) }
 
# data series
   [void]$chartobject.Series.Add("PrivateMemory")
   $chartobject.Series["PrivateMemory"].ChartType = "Column"
   $chartobject.Series["PrivateMemory"].IsVisibleInLegend = $true
   $chartobject.Series["PrivateMemory"].BorderWidth  = 3
   $chartobject.Series["PrivateMemory"].chartarea = "ChartArea1"
   $chartobject.Series["PrivateMemory"].Legend = "Legend1"
   $chartobject.Series["PrivateMemory"].color = "#bf00ff"
   $topCPUUtilization | ForEach-Object {$chartobject.Series["PrivateMemory"].Points.addxy( $_.Name , ($_.PrivateMemorySize / 1000000)) }
 
# save chart with the Time frame for identifying the usage at the specific time
   $chartobject.SaveImage("$chartSavePath\CPUusage_$(get-date -format `"yyyyMMdd_hhmmsstt`").png","png")

 

OUTPUT:

How To Monitor a Folder changes using Powershell

In our environment, large numbers of users are working on a daily basis and it very difficult to track what file they have modified and which time. To handle this scenario, my team was requested to monitor a directory for any file changes and receive alerts of those changes when they trying to update/Delete/renamed/created in a specific location inside the service and this requirement made me create this post. In this post, we will discuss how to monitor changes in the folder including sub-files, and log in to the log text file.

STEP #1

To monitor a folder for new files in Windows with PowerShell, we can use a .NET class called FileSystemWatcher. This class is in the System.IO namespace and can be created with the New-Object cmdlet.

$filewatcher = New-Object System.IO.FileSystemWatcher

STEP #2

To monitoring a folder/all sub-folders we need to assign the IncludeSubdirectories property as true.

$filewatcher.IncludeSubdirectories = $true

STEP #3

Then you need to specify which folder you I’ll be monitoring and also set the EnableRaisingEvents property to $true. The component is set to watch for changes in the last write and last access time, the creation, deletion, or renaming of text files in the directory. It will not raise events unless you set EnableRaisingEvents to true.

$filewatcher.EnableRaisingEvents = $true

STEP #4

In below code we using built-in [$event] variable. This is a variable that will be present every time an event fires and contains information such as the file path and the type of event that fired. In this script block, we capturing all the events in the FileWatcher_log.txt while event is fired.

$writeaction = { $path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType
$logline = “$(Get-Date), $changeType, $path”
Add-content “C:\D_EMS Drive\Personal\LBLOG\FileWatcher_log.txt” -value $logline
}

STEP #5

Finally, we need to register for the events. To perform this you need to use the Register-ObjectEvent cmdlet and need to supply it the watcher object we created and type of action to monitor like “Created”,”Changed”,”Deleted”,”Renamed”. The Register-ObjectEvent cmdlet subscribes to events that are generated by .NET objects on the local computer or on a remote computer.

Register-ObjectEvent $filewatcher “Created” -Action $writeaction
Register-ObjectEvent $filewatcher “Changed” -Action $writeaction
Register-ObjectEvent $filewatcher “Deleted” -Action $writeaction
Register-ObjectEvent $filewatcher “Renamed” -Action $writeaction

After executing the script, it will start to monitor the folder and sub-items from the given path and log the details in the FileWatcher_log.txt file.

Full Example

### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
    $filewatcher = New-Object System.IO.FileSystemWatcher
    #Mention the folder to monitor
    $filewatcher.Path = "C:\D_EMS Drive\Personal\LBLOG\"
    $filewatcher.Filter = "*.*"
    #include subdirectories $true/$false
    $filewatcher.IncludeSubdirectories = $true
    $filewatcher.EnableRaisingEvents = $true  
### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
    $writeaction = { $path = $Event.SourceEventArgs.FullPath
                $changeType = $Event.SourceEventArgs.ChangeType
                $logline = "$(Get-Date), $changeType, $path"
                Add-content "C:\D_EMS Drive\Personal\LBLOG\FileWatcher_log.txt" -value $logline
              }    
### DECIDE WHICH EVENTS SHOULD BE WATCHED 
#The Register-ObjectEvent cmdlet subscribes to events that are generated by .NET objects on the local computer or on a remote computer.
#When the subscribed event is raised, it is added to the event queue in your session. To get events in the event queue, use the Get-Event cmdlet.
    Register-ObjectEvent $filewatcher "Created" -Action $writeaction
    Register-ObjectEvent $filewatcher "Changed" -Action $writeaction
    Register-ObjectEvent $filewatcher "Deleted" -Action $writeaction
    Register-ObjectEvent $filewatcher "Renamed" -Action $writeaction
    while ($true) {sleep 5}

OUTPUT:

What do you think?

I hope you have an idea of  Monitoring a Folder Using PowerShell Scripting with Powershell. I would like to have feedback from the readers of my post. Your valuable feedback, question, or comments about this article are always welcome.

How to encrypt and store Passwords securely in PowerShell

As a system Admin, managing automation scripts passwords in PowerShell is a tricky task. There is always risk that someone may find the password by simply taking your code from server or automation tool. To overcome this critical scenarios, in all our automation we have call for stored encrypted password somewhere and referencing it in a script for authentications.

In PowerShell you can store sensitive information on disk is through secure strings. Secure strings are just like they simple strings encrypted through the logged-in user’s certificate. Creating a secure string is very easy and simple by using the ConvertTo-SecureString command from the powershell and it will still reduce the risk by a significant amount depending on the method

Step 1: Create your encrypted password file.

Method 1: Using your login credential as password.

First you need a standalone .ps1 script to generate your password file with Encryption string. Here we are encrypting your credential as password. The following code will achieve this

#Set and encrypt credentials to file using default ConvertFrom-SecureString method
(get-credential).password | ConvertFrom-SecureString | set-content “C:\D_EMS Drive\Personal\LBLOG\Encrypted_password.txt”

After executing above script, you will get a prompt for the password, then input your credentials that you want to save. In our example an encrypted password file will be saved to “C:\passwords\password.txt”. 

After executing the above code,  the prompt window will popup for getting the user name and Password like above, and script will encrypt the same password in the text file as shown below.

Method 2: Encrypt password by input value

Let’s say if you having a password and that need to encrypt by asking as input then the below script will prompt for input via the Read-Host command using the AsSecureString parameter, which will obfuscate your input and return a secure string as shown below.

$securePassword = Read-host -AsSecureString | ConvertFrom-SecureString
$securePassword | Out-File -FilePath “C:\D_EMS Drive\Personal\LBLOG\Encrypted_password.txt”

After execution of the above script, you can able to look at that variable’s value, it’s clear your input is encrypted.  Then the encrypted password will be save to the text file.

Step 2: Use the Encrypted password in the powershell script to authenticate.

Now, how do we retrieve these credentials? Easy, if we ever need to retrieve these we include the following syntax in our scripts to provide the creds.
Then just pass $credential to whatever cmdlets need a pscredential to authenticate. If we look at what’s in the $credential variable we can see our username and its encrypted password.

Now you have a password with file name “Encrypted_password” stored securely on disk as encrypted format. At this point, if you need to retrieve it from the file. To do this, you can use Get-Content to read the file and then create a PSCredential object from the secure string.

$username = “SysAdmin”
$password = Get-Content “C:\D_EMS Drive\Personal\LBLOG\Encrypted_password.txt” | ConvertTo-SecureString
$credential = New-Object System.Management.Automation.PsCredential($username,$password)

 

What do you think?

I hope you have an idea of  How to encrypt and store credentials securely for use with automation scripts with Powershell. I would like to have feedback from my posts readers. Your valuable feedback, question, or comments about this article are always welcome.

How to Get average CPU usage of a computer in last x minute with Powershell

We got the requirement to monitor the performance for few minutes before starting the activity (CPU usage of a computer in last x minute ) in the PRODUCTION server and requested this to be automate instead of getting in to the server each time. The below same we have implemented in the our build Tool to make it automatic.

How to achieve?

We can achieve the above scenario by using the Get-Counter cmdlet in Powershell. It will gets performance counter data directly from the performance monitoring instrumentation in the Windows family of operating systems. Get-Counter gets performance data from a local computer or remote computers.

STEP 1: This below line will check the CPU usage of last 5 times with 1 second intervals. as shown below.

Get-counter -Counter “\Processor(_Total)\% Processor Time” -SampleInterval 1 -MaxSamples 5

STEP 2: Selecting the Counter Samples and calculating the Average of the CPU Usage.

select -ExpandProperty countersamples | select -ExpandProperty cookedvalue | Measure-Object -Average).average

 

Full Code

The following script will return the average CPU % over a period of 5 seconds with 5 samples averaged. The $_.CookedValue is a variable for the current object in the pipeline.

###################################################################################
#Project : How to Gets CPU performance counter data from local and remote computers.
#Developer : Thiyagu S (dotnet-helpers.com)
#Tools : PowerShell 5.1.15063.1155 
#E-Mail : mail2thiyaguji@gmail.com 
###################################################################################

#-SampleInterval: parameter to increase the interval between continuous samples,
#If the SampleInterval parameter isn't specified, Get-Counter uses a one-second interval.

#-MaxSamples : Specifies the number of samples to get from each specified performance counter
#If the MaxSamples parameter isn't specified, Get-Counter only gets one sample for each specified counter.
$CPUAveragePerformance = (GET-COUNTER -Counter "\Processor(_Total)\% Processor Time" -SampleInterval 2 -MaxSamples 5 |select -ExpandProperty countersamples | select -ExpandProperty cookedvalue | Measure-Object -Average).average

Write-Host "Average of CPU usage (calculated with 5 Sample with interval of 2 sec) :" $CPUAveragePerformance

OUTPUT:

 

What do you think?

I hope you have an idea of  How to Get average CPU usage of a computer in last x minute with Powershell. I would like to have feedback from my posts readers. Your valuable feedback, question, or comments about this article are always welcome.

How to combine the elements of two arrays using Powershell

An array is a data structure that is designed to store a collection of items. The items can be the same type or different types. PowerShell (like most other languages) stay the same length once you create them. To combine two arrays, PowerShell creates a new array large enough to hold the contents of both arrays and then copies both arrays into the destination array.

If you plan to add and remove data from an array frequently, the System. Collections.ArrayList class provides a more dynamic alternative. In this post, we are going to discuss the different way of scenarios for combining the two Array and output with a single Array

Example 1:

If you want to join arrays in Powershell, especially if you don’t know if one or more of the objects you are joining are arrays or single objects, combine them with the addition ‘+’ operator and cast the first item as an array.

Remove-Variable -Name "fullName"
$firstName = @("Rakshu","Aadharsh","Aadhira")
$lastName = @("T.A","G.K","G.K")
$fullName = $lastName + $firstName
$fullName

OUTPUT:

Example 2:

If you like to join two arrays by fetching the elements from each array one by one and not have them combined or simply merged.

Remove-Variable -Name "Result"
$Result = @()
$firstName = @("Jon","Bob","Tom")
$lastName = @("Smith","Jones","White")
$MaxLength = [Math]::Max($firstName.Length, $lastName.Length)
for ($loop_index = 0; $loop_index -lt $MaxLength; $loop_index++)
{ 
    $Result+=$firstName[$loop_index]
    $Result+=$lastName[$loop_index]
}

$Result

OUTPUT:

Example 3:

In this example, you can see how to Combine Individual Items From Separate Arrays Into a Third Array. Below example, we having two arrays, one with a list of first names and a second with a list of last names. The third Array will have the result of combining the first name and the last name that reside at the same index position in their respective arrays into a third array (combine them and output them with column headers). Example as follows:

$firstName = @("Rakshu","Aadharsh","Aadhira")
$lastName = @("T.A","G.K","G.K","max","mike","Jen","raju")
[int]$max = $firstName.Count
if ([int]$lastName.count -gt [int]$firstName.count) { $max = $lastName.Count; }

$Results = for ( $i = 0; $i -lt $max; $i++)
{
    Write-Verbose "$($firstName[$i]),$($lastName[$i])"
    [PSCustomObject]@{
        FirstName = $firstName[$i]
        LastName = $lastName[$i]

    }
}

OUTPUT:

What do you think?

I hope you have an idea of How to join the elements of two arrays using Powershell. I would like to have feedback from the readers of my post. Your valuable feedback, question, or comments about this article are always welcome.

How to Use PowerShell to Detect Logins and Alert Through Email using SendGrid

From Microsoft MSDN, The Get-WinEvent data from event logs that are generated by the Windows Event Log technology introduced in Windows Vista.And, events in log files generated by Event Tracing for Windows (ETW).By default, Get-WinEvent returns event information in the order of newest to oldest.

Get-winevent : Gets events from event logs and event tracing log files on local and remote computers. The Get-WinEvent cmdlet uses the LogName parameter to specify the Windows PowerShell event log. The event objects are stored in the $Event variable.

This script reads the event log “Microsoft-Windows-TerminalServices-LocalSessionManager/Operational” from servers and outputs the human-readable results to Mail. The -MaxEvents 1 Specifies the maximum number of events that are returned. Enter an integer such as 100. The default is to return all the events in the logs or files.

#################################################################
#Project : How to Use PowerShell to Detect Logins and Alert Through Email using SendGrid
#Developer : Thiyagu S (dotnet-helpers.com)
#Tools : PowerShell 5.1.15063.1155 
#E-Mail : mail2thiyaguji@gmail.com 
##################################################################

$Timestamp = [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId((Get-Date), 'India Standard Time')
$Text = "Timelines in IST"
$EmailBody = get-winevent -filterhashtable @{logname='Microsoft-Windows-TerminalServices-LocalSessionManager/Operational';id=21} -MaxEvents 1 | Format-List -Property TimeCreated,Message
$EmailFrom = "servermonitor@dotnet-helpers.com"
$EmailTo = "dotnet-helpers@accenture.com mail2thiyaguji@gmail.com"
$EmailSubject = "Server Login Notification"
$SMTPServer = "smtp.sendgrid.net"
[string][ValidateNotNullOrEmpty()] $Username = "azure_ad8e8e784erf789.com"
[string][ValidateNotNullOrEmpty()] $pwd = "xxxxxxxxxxx"
$pwd1 = ConvertTo-SecureString -String $pwd -AsPlainText -Force
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $Username, $pwd1
$SMTPPort = 587
Send-MailMessage -From $EmailFrom -To $EmailTo -Subject $EmailSubject -body ($EmailBody + "($Text)" + "($Timestamp)" | Out-String) -SmtpServer $SMTPServer -Port $SMTPPort -Credential $cred 

The Windows Task Scheduler can automatically send email at a specific time or in response to a specific event. The below article will help to configure the script in Windows Scheduler Task

Here i setting this script to execute the script if any user log in to the server, so it will intimate to the supervisor by triggering mail. Go to Triggers tab and add a new trigger. The trigger should be set to fire at log on, which can be selected from the drop down.

OUTPUT:

How to delete files older than 30 days automatically using PowerShell

Delete files older than 30 days:

In many scenario we will store large number of non-important files on a different location, and its very difficult to delete those huge files old files monthly wise, to handle such scenario we are here going to use PowerShell and Task Scheduler to monitor and clean up files from any folder that are older than a specified number of days.

In this post, you’ll learn the steps to automatically delete files that haven’t been modified in the last month or any number of days you specify on Windows. The below scripts will delete the files that haven’t been modified in the last 30 days.

#################################################################
#Project : How to delete the old file automatically using Powershell
#Developer : Thiyagu S (dotnet-helpers.com)
#Tools : PowerShell 5.1.15063.1155 
#E-Mail : mail2thiyaguji@gmail.com 
##################################################################
Get-ChildItem –Path "C:\PowerShell\OriginalFolder" -Recurse | 
Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays(-30))} | Remove-Item

In the above command remember to change “C:\path\to\folder” specifying the path to the folder that you want to delete files, and change -30 to select files with a last modified date.

How to use Task Scheduler to delete files older than 30 days automatically using Powershell:

In above code we have created Powershell script for deleting the files older than 30 day, but our scenario is want to delete automatically, Most we will use the graphic interface of Taskschd.msc console to create Windows Task Scheduler jobs and Building a single scheduled task via the GUI task scheduler might not be a big deal. But if you find yourself creating scheduled tasks repeatedly it might be a good idea to use a method that scales better than a GUI like PowerShell. However, in various scripts and automated jobs, it is much more convenient to use the PowerShell features to create scheduled tasks. In this below link, we have detail description about how to create new Windows Scheduler tasks using PowerShell.

.

How to Read Multiline User Input in Powershell

Here we will discuss about reading multi line inputs from command line using PowerShell. In some time we often get requirement to enter multiple lines or paragraphs of text as input to a PowerShell script, so we are going to discuss in this article.

Here logic is very simple, the Get-MultiLineInput function will repeatedly call Read-Host till the value entered by the user with “exit”. If user enter with “exit” then immediately it will stopping the loop.

#################################################################
#Project : How to Read Multiline User Input in Powershell
#Developer : Thiyagu S (dotnet-helpers.com)
#Tools : PowerShell 5.1.15063.1155 
#E-Mail : mail2thiyaguji@gmail.com 
##################################################################
function Get-MultiLineUserInputs {
[CmdletBinding()]
param(
)
$userinputstring = @()
$userinput = $null
while($userinput -ne "exit") {
    $userinput = Read-Host
    if($userinput -eq "exit") {
        Continue
    } else {
        $userinputstring += $userinput
 
    }
}
 
return $userinputstring
 
}
Write-Host "`nEnter your inputs (type 'exit' to finish)`n"  -ForegroundColor Green
$multilines = Get-MultiLineUserInputs
Write-Host "`nOUTPUT`n"  -ForegroundColor Green
-join $multilines

OUTPUT: