Friday 3 September 2021

PowerShell Menu

function Show-Menu
{
    Write-Host "================ Title ================"
    Write-Host "1: Press '1' for this option."
    Write-Host "2: Press '2' for this option."
    Write-Host "3: Press '3' for this option."
    Write-Host "Q: Press 'Q' to quit."
}

do{
    Show-Menu 
    $selection = Read-Host "Please make a selection"
    switch ($selection)
    {
        '1' {
            'You chose option #1'
               Write-Host `n
        } 
        '2' {
            'You chose option #2'
               Write-Host `n
        } 
        '3' {
            'You chose option #3'
               Write-Host `n
        } 
        'q' {
            return
        }
        default{
        Write-Host "Invalid Selection"
        Write-Host `n
        }
    }
}
until($selection -eq 'q')

Tuesday 24 August 2021

Calculate Time to Run the Script


 $starttime = (Get-Date)
    get-mailox

$endtime = (Get-Date)
Write-Host "`n`nTotal Time : $(($endtime-$starttime).totalseconds) Seconds"

Friday 20 August 2021

Try Catch and Send Email

try
{
 It will generate error
}
catch
{
    Write-host $_.Exception.Message -ForegroundColor Yellow
    Write-host $_.Exception.ItemName -ForegroundColor Green
    $ErrorMessage = $_.Exception.Message 
    $FailedItem = $_.Exception.ItemName
    $cred = Get-Credential
    Send-MailMessage -From Sender@domain.com -To Recipient@domain.com -Subject "Script Failed!" -SmtpServer smtp.office365.com -Body "We failed to read file $FailedItem. The error message was $ErrorMessage" -Port 587 -Credential $cred -BodyAsHtml -UseSsl 
    Continue
}
 

Convert CSV to Excel

# Collect all CSV name in a TXT File
(get-childitem "C:\SUMANT\test").FullName > C:\SUMANT\CSVName.txt

(gc "C:\SUMANT\CSVName.txt") | foreach-object{
    [string]$csv = $_
    
    $xlsx = ($csv).replace("csv","xlsx")
    $xl = New-Object -ComObject "Excel.Application"
    $xl.Visible=$False
    $wb = $xl.Workbooks.Open($csv)
    $wb.SaveAs($xlsx, 51)
    $xl.Quit()

Thursday 19 August 2021

Email Queue Report

 Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010;

$Output = $null
$HtmlReport = $null
$Output = [system.collections.arraylist]@()
$HtmlReport=@()

$head = @"
<style>
h1, h5, th { text-align: center; }
table { margin: auto; font-family: Segoe UI; box-shadow: 10px 10px 5px #888; border: thin ridge grey; }
th { background: #0046c3; color: #fff; max-width: 400px; padding: 5px 10px; }
td { font-size: 11px; padding: 5px 20px; color: #000; }
tr { background: #b8d1f3; }
tr:nth-child(even) { background: #dae5f4; }
tr:nth-child(odd) { background: #b8d1f3; }
</style>
"@

$Server = @(
"Server001"
"Server002",
"Server003",
"Server004"
)
foreach($s in $Server)
{
    Write-Host "`n"
    Write-Host "Queue Status for Server: " -ForegroundColor Yellow -NoNewline
    Write-Host "$s" -ForegroundColor Green
    $body="<h3>[ $($s) ] Queue Report: on $(Get-Date)</h3>"
    $data= Get-Queue -Server $s |?{$_.DeliveryType -notlike "*ShadowRedundancy*" } | sort messagecount -Descending| `
Select Identity,DeliveryType,Status,MessageCount,NextHopDomain 
    Write-Host "[ Completed ]" -ForegroundColor Cyan
    $null =$output.Add($data)
    $HtmlReport += $data | ConvertTo-Html -Body $body -Head $head 
}
$Output|Sort-Object MessageCount -Descending|ft

# Details of the Login Username and SMTP server. These can very from one 
$SMTPServer = "smtprelay.office365.com"
$SMTPPort = "25"
#$Username = "sumant.prasad@test.com"
#$Password = "Password"
#Add email address of person in to & cc  whom you are sending email (Multiple addresses should be comma seperated)
$to = "Messaging@test.com,MessagingHealthReport@test.com"
#$cc = "sumant.prasad@test.com"
$subject = "All Location Email Queue Report"
$message = New-Object System.Net.Mail.MailMessage
$message.subject = $subject
$message.body = $HtmlReport
$message.to.add($to)
#$message.cc.add($cc)
$message.IsBodyHtml = $True
$message.from = "MessagingHealthReport@intertrustgroup.com"

<#If needed to send file as attachment
$attachment = "$Path\CaymanMailboxPermission.csv"
$attach_log = new-object Net.Mail.Attachment($attachment)
$message.Attachments.Add($attachment)
#>

$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
#$smtp.EnableSSL = $true
#$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
$smtp.send($message)
Write-Host "Email Sent"

Wednesday 18 August 2021

Event Log Error Details

 Param(

        [string]$LogName = "System",
        [string]$ComputerName = $env:COMPUTERNAME,
        [int]$Newest = 500,
        [string]$ReportTitle = "Event Log Report",
        [Parameter(Mandatory,HelpMessage = "Enter the path for HTML")]
        [string]$Path
)
        $data = Get-EventLog -LogName System -EntryType Error -Newest $Newest -ComputerName $ComputerName |`
        Group-Object -Property Source -NoElement

        #Create an HTML report
        $title = "System Log Analysis"
        $footer = "<h5><i>Report Run $(get-date)</i></h5>"
        $css = "https://jdhitsolutions.com/sample.css"
        $precontent = "<h1>$ComputerName</h1><h2>Last $Newest error sources from $LogName</h2>" 
        $data | Sort-Object -Property count,name -Descending | select count,name | `
        ConvertTo-Html -Title $title -PreContent $precontent -PostContent $footer -CssUri $css | Out-File "D:\Sumant\test.html"

Sunday 23 May 2021

REGEX Match


$a=Read-Host "Enter Value : "

if($a -match '^(sumant|ajay|kumar)' ){

    Write-Output "Matched"

}

else {

    Write-Output "Not Matched"



Monday 3 May 2021

Start-Process with a Special Name or Handle to Kill It


Write-Output " Creating a new PowerShell Session"

$arg = {"$Host.UI.RawUI.WindowTitle='MySession'";"&'F:\Scripts\LicMgmt .ps1'";}

$StartInfo = new-object System.Diagnostics.ProcessStartInfo

$StartInfo.FileName = "$pshome\powershell.exe"

$StartInfo.Arguments = $arg

[System.Diagnostics.Process]::Start($StartInfo) 


To Check your Open Session/Kill It

Get-Process|where-object{($_.MainWindowTitle) -match '^(Select MySession|MySession)'}|Stop-Process




Wednesday 21 April 2021

Get User Data using Rest API [Python]


# Installing o365 module
# pip install O365

from O365 import Account

credentials = ('Clien_Id', 'Client_Secret')


account = Account(credentials, auth_flow_type='credentials', tenant_id='Tenant_Id')
if account.authenticate():
print('Authenticated!')


directory = account.directory()
for user in directory.get_users():

print(user)



Saturday 17 April 2021

Open URL in a browser in PowerShell

 

Open URL in default browser Using PowerShell

Start-Process "https://microsoft.com"



Open URL in Google Chrome Using PowerShell

[system.Diagnostics.Process]::Start("chrome","https://microsoft.com")


Open URL in Microsoft Edge Using PowerShell

[system.Diagnostics.Process]::Start("msedge","https://microsoft.com")


Open URL in Internet Explorer Using PowerShell

[system.Diagnostics.Process]::Start("iexplore","https://microsoft.com")

Friday 16 April 2021

Graph Explorer

 

Microsoft Graph Explorer


MetaData

MetaData is like Get-Member which shows all properties can be called using Graph API. It includes Property Name, NavigationProperty Name [Related Object].


Open Browser

https://graph.microsoft.com/v1.0/$metadata 


Look For : 

EntityType name="User"

EntityType name="group"




OData : Open Data is a protocol that is used for a creation of an API’s which is used to expose data over https.


$VarInvoke-RestMethod -Uri "https://graph.microsoft.com/v1.0"



Kind Property

  • EntitySet

  • Singleton



DirectoryReadAll : Will provide you User license details




Microsoft Graph API


HTTP Methods

Request Structure




PATCH [Update] : Requires UserReadWriteAll Permission






Microsoft Graph User

https://graph.microsoft.com/beta/$metadata 


Find : 

EntityType Name="user"



Property Name

NavigationProperty Name [Related Object] 





https://graph.microsoft.com/beta/users/rohit@rohit.club/manageddevices





Microsoft Graph Delta Endpoints






When you perform Delta then only the incremental value of all the users will be displayed.

'https://graph.microsoft.com/v1.0/users/delta'



If you want to have specific data which are changed then you have to Copy the @odata.nextLink value and paste it to the GET Box


Copy and keep the “@odata.nextLink” value which is generated this time if you want to see the incremental data changed for the day.









Graph Explorer Query


https://docs.microsoft.com/en-us/graph/query-parameters#error-handling-for-query-parameters 









Combining Two Query (&)

https://graph.microsoft.com/v1.0/users?$select=displayName,userPrincipalName&$count=true&$top=3



Microsoft Graph Pagination


When the API Server is unable to send all the data at once then the Server follows the paging process where it will send the 1st page with @odata.nextlink which is the link for the next page. This is called Server Side Paging.




Client/Application defines the page size $top=2 which needs to be received by a Server called Client Side Pagination.

Microsoft Graph Batching




Batching is the process of combining multiple Queries into one single Query and sending it to Microsoft Graph API.


Example:






Oauth 2.0 Client Credential Flow


This type of grant is commonly used for server-to-server interactions that must run in the background, without immediate interaction with a user. These types of applications are often referred to as daemons or service accounts.

The Endpoint will be used for this type of flow is Token endpoint. 

&Grant_Type=Client_Credentials(check the below image)

Open Id Connect



Saturday 10 April 2021

Splatting in PowerShell


#Example 1
##########

    $Params = @{
        "Path"        = "TestFile.txt"
        "Destination" = "CopiedFile.txt"
        "WhatIf"      = $True
        "Force"       = $True
      }
  
      Copy-Item @Params


#Example 2
##########

  $MailMessage = @{
    To = “me@mycompany.com
    From = “me@mycompany.com
    Subject = “Hi”
    Body = “Hello”
    Smtpserver = “smtphost”
    ErrorAction = “SilentlyContinue”
}

Send-MailMessage @MailMessage 


Execution Policy

 1. Restricted 

This is the default. PowerShell will not run any script, including PowerShell profiles.

2. RemoteSigned 

PowerShell will run any script that you create locally. But any script that has been detected as coming from the Internet, such as via Internet Explorer, Microsoft Outlook, Mozilla Firefox or Google Chrome must be digitally signed with a code signing certificate that is trusted by the computer.

3. AllSigned 

PowerShell will not run any script unless it has been digitally signed with a trusted code signing certificate.

4. Unrestricted 

PowerShell will make no attempts to hinder script execution and will run any script. If the script comes from an untrusted source, like the Internet, you will be prompted once to execute it. Though it is not preferred.

5. Bypass 

There is also a Bypass policy, which I don’t recommend for daily use. This policy will run any script without question or prompting. The assumption is that you have taken steps outside of Nothing is blocked and there are no warnings or prompts.PowerShell to verify the safety and integrity of the script.

6. Undefined 

There is no execution policy set in the current scope. If the execution policy in all scopes is Undefined, the effective execution policy is Restricted, which is the default execution policy.




Write-Error vs. Throw in PowerShell

 

Write-Error should be used if you want to inform the user of a non-critical error. By default all it does is print an error message in red text on the console. It does not stop a pipeline or a loop from continuing.


 Throw on the other hand produces what is called a terminating error. If you use throw, the pipeline and/or current loop will be terminated. In fact all execution will be terminated unless you use a trap or a try/catch structure to handle the terminating error.




Credentials objects in PowerShell

 

$UserName = 'Sumant'

    $Password = 'Password@123' | ConvertTo-SecureString -AsPlainText -Force

    

    # method 1

    [pscredential]::new($Username,$Password)

    

    # method 2

    New-Object System.Management.Automation.PSCredential($UserName,$Password)

Pipeline ByValue and ByPropertyName

 Accept pipeline input ByValue

Get-Process|Gm

Will return TypeName: System.Diagnostics.Process


Thats why Get-Process -Name notepad|Stop-Process Works. 

Get-Process (Retrive Type Process Objects)

Stop-Process (Accepts Type Process Objects)

Its mapped to the below parameter which is ByValue

-InputObject <Process[]>

    Required?                    true

    Position?                    Named

    Accept pipeline input?       true (ByValue)

    Parameter set name           InputObjectWithUserName, InputObject

    Aliases                      None

    Dynamic?                     false


 Stop-Process [-InputObject] <Process[]> [-PassThru] [-Force] [-WhatIf] [-Confirm]  [<CommonParameters>]

By default pipeline uses ByValue and if that is not available then its uses ByPropertyName 


Accept pipeline input ByPropertyName

"notepad"|Stop-Process will Fail.

Stop-Process : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the

parameters that take pipeline input.

"notepad" : Considered as byValue and Stop-Process Accept pipeline input ByPropertyName

-Name <string[]>

    Required?                    true

    Position?                    Named

    Accept pipeline input?       true (ByPropertyName)

    Parameter set name           Name

    Aliases                      ProcessName

    Dynamic?                     false


Stop-Process -Name <string[]> [-PassThru] [-Force] [-WhatIf] [-Confirm]  [<CommonParameters>]


But we can force it by using the below command

[pscustomobject]@{name="notepad"}|Stop-Process. This time it will Accept pipeline input ByPropertyName


Wednesday 31 March 2021

Fetch User Details using Graph API

 

Param(
    $ApplicationID,
    $TenatDomainName,
    $AccessSecret
)

#Defining Application Details
$ApplicationID = "44b78d78-425a-446567-21527-a43kj39k2t0a8"
$TenatDomainName = "spscript.onmicrosoft.com"
$AccessSecret = "cba)b@Q~p~Ygk*%F~gcf27%170_g@#30~"

#Requesting Token
$Body = @{    
Grant_Type    = "client_credentials"
Scope         = "https://graph.microsoft.com/.default"
client_Id     = $ApplicationID
Client_Secret = $AccessSecret

$ConnectGraph = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenatDomainName/oauth2/v2.0/token" -Method POST -Body $Body

#Token Received and stored in Token Variable
$token = $ConnectGraph.access_token


#Fetching User Details 
$UsersURL = 'https://graph.microsoft.com/beta/Users/'
$Result = Invoke-RestMethod -Headers @{Authorization = "Bearer $($token)"} -Uri $UsersURL -Method Get

$Result.value|Select-Object userPrincipalName