TechOnTip Weblog

Run book for Technocrats

Ruthless Prioritization

Posted by Brajesh Panda on February 24, 2022

Posted in Mix & Match | Leave a Comment »

Teams Voice 1 – Basics of SIP Communication

Posted by Brajesh Panda on February 6, 2022

It is always good to review some basics.

Posted in Mix & Match | Leave a Comment »

100 Days Cycle Ride Program

Posted by Brajesh Panda on January 27, 2022

After 20yrs I am riding cycle and this is for good. Going with full throttle for the last 70+ days after I bought the hybrid cycle. Let’s see if I can reach 10,000 points by end of 100 days 😉 I am also able to convince two of my colleagues to get on the saddle. Helps me to avoid self burnout in this corporate world.

Posted in Mix & Match | Leave a Comment »

Enable Bulk AD Security Permissions Inheritance – Powershell

Posted by Brajesh Panda on December 21, 2021

$ADusers = Get-ADUser -ldapfilter "(objectclass=user)" -searchbase "OU=Employees,DC=blisspanda,DC=local"
ForEach($user in $ADusers)
{
    # Binding the users to DS
    $ou = [ADSI]("LDAP://" + $user)
    $sec = $ou.psbase.objectSecurity
 
    if ($sec.get_AreAccessRulesProtected())
    {
        $isProtected = $false ## allows inheritance
        $preserveInheritance = $true ## preserver inhreited rules
        $sec.SetAccessRuleProtection($isProtected, $preserveInheritance)
        $ou.psbase.commitchanges()
        Write-Host "$user is now inherting permissions";
    }
    else
    {
        Write-Host "$User Inheritable Permission already set"
    }

Posted in Mix & Match | Tagged: | Leave a Comment »

Feeling Delighted – 100 days run challenge

Posted by Brajesh Panda on October 31, 2021

Very first time I have participated in HDOR 100 days run challenge. Not a perfect finish but a good one with 90 days of run, covering 680.8km in 85h 8m of activities. The average pace came about 7:30mins/km. Well, the biggest progress is on long runs. I have been running on and off since 2016 but never thought to put it into the routine and never crossed 10k. This helped me to create a running group with my buddies and pushed me to finish 3 Half Marathons, 2 of those paced by buddies, and the 3rd one solo with minimum hydration, finishing 23.36km in 2hr 29mins.

Hipp Hipp hurray!!

Posted in Mix & Match | 1 Comment »

TXT/Config file edit – Powershell

Posted by Brajesh Panda on October 11, 2021

This tiny script saved me quite few times. Hope this helps you too.

# Get file path
$Path = "FilePath.Agent.exe.Config"
Get-Item $Path

# Create a new name to backup the original file
$NewName = $Path + '.bak'
# Get content of the file including the encoding
$Content = Get-content $Path -Raw -Encoding Ascii
# Rename the orignial file to new name
Rename-Item $Path -NewName $NewName -Force
# Generate a new file after replacing necessary text
$Content -replace 'ServerA.DomainA.com','ServerA.DomainB.com' | Out-File $Path -Encoding ascii
# Happy Happy

To check encoding of existing file here is a nice script 😉

https://community.idera.com/database-tools/powershell/powertips/b/tips/posts/get-text-file-encoding

function Get-Encoding
{
  param
  (
    [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
    [Alias('FullName')]
    [string]
    $Path
  )

  process 
  {
    $bom = New-Object -TypeName System.Byte[](4)
        
    $file = New-Object System.IO.FileStream($Path, 'Open', 'Read')
    
    $null = $file.Read($bom,0,4)
    $file.Close()
    $file.Dispose()
    
    $enc = [Text.Encoding]::ASCII
    if ($bom[0] -eq 0x2b -and $bom[1] -eq 0x2f -and $bom[2] -eq 0x76) 
      { $enc =  [Text.Encoding]::UTF7 }
    if ($bom[0] -eq 0xff -and $bom[1] -eq 0xfe) 
      { $enc =  [Text.Encoding]::Unicode }
    if ($bom[0] -eq 0xfe -and $bom[1] -eq 0xff) 
      { $enc =  [Text.Encoding]::BigEndianUnicode }
    if ($bom[0] -eq 0x00 -and $bom[1] -eq 0x00 -and $bom[2] -eq 0xfe -and $bom[3] -eq 0xff) 
      { $enc =  [Text.Encoding]::UTF32}
    if ($bom[0] -eq 0xef -and $bom[1] -eq 0xbb -and $bom[2] -eq 0xbf) 
      { $enc =  [Text.Encoding]::UTF8}
        
    [PSCustomObject]@{
      Encoding = $enc
      Path = $Path
    }
  }
}

Posted in Mix & Match | Tagged: | Leave a Comment »

Validate Password – Powershell

Posted by Brajesh Panda on October 6, 2021

# I have been using this tiny script to run security audits. Helps us to understand if any generic passwords is used by users. Then add the password to Azure AD Password Protection tool's block list and push users for security training. 

Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File Test.txt
$username = "User ID"
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ContextType = [System.DirectoryServices.AccountManagement.ContextType]::Domain
$ContextOptions = [System.DirectoryServices.AccountManagement.ContextOptions]::Negotiate
$PrincipalContext = New-Object System.DirectoryServices.AccountManagement.PrincipalContext($ContextType, $env:USERDNSDOMAIN)
$password = cat Test.txt | convertto-securestring
$Cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
$PrincipalContext.ValidateCredentials($cred.UserName, $cred.GetNetworkCredential().password, $ContextOptions)

# Result will be True for successfull validation or False

Posted in Mix & Match | Tagged: | 1 Comment »

Bitlocker Report – Powershell

Posted by Brajesh Panda on September 2, 2021

Below script will retrieve all recovery keys from the active directory. Make sure you have domain admin or bitlocker viewer access.

Get-ADObject -Filter {objectclass -eq 'msFVE-RecoveryInformation'} -Properties * | `
            select @{n="Name";e={$_.CanonicalName.Split("/")[-2]}}, msFVE-RecoveryPassword, Modified,   @{n="DN";e={$_.CanonicalName.Replace("/"+$_.CN, "")}}

Posted in Mix & Match | Leave a Comment »

Art Of Speech – By Late Mr. Pramod Mahajan

Posted by Brajesh Panda on March 13, 2021

After a long sabbatical from my blogging, thought to get back again. Recently, I came across this great video about the Art of Speech by late Mr. Pramod Mahajan on Facebook. It was only for 13 minutes. So, ran a google search and found the full video of 50 minutes on BJP Maharashtra’s youtube channel. If you don’t know, he was a politician with Bharatiya Janata Party i.e. BJP. Doesn’t matter if you ideologically like his party or not, but this speech can be great for learning Public Speaking skills.

https://youtu.be/gjZNBZLLyjY

Posted in Mix & Match | Tagged: , | Leave a Comment »

Azure AD or Office 365 License Assignment Audit Report

Posted by Brajesh Panda on February 27, 2020

# Author: Brajesh Ranjan Panda
# Blog:  https://technotip.wordpress.com
# Creates Azure AD License Assignment Report
# Output: ActivityDate	result	TargetUser	InitiatedBy	OldLicenseSKU	NewLicenseSKU	correlationId	country	officelocation	accountEnabled
# Microsoft Graph API calls are used to pull down Azure AD Audit Logs then selective output to CSV
# Last update: Feb 28, 2020

# Auth Secrets from Azure AD Application - Graph API (Web App)
# You have to register an application and give the application access to Read Azure Audit Logs and Directory

# Insert your application's Client ID, a Globally Unique ID (registered by Global Admin)
$ClientID = "App ID"

# Insert your application's Client Key/Secret string                                       
$ClientSecret = "Client Secret"                        
<#
# If you want to use from a secure string use below steps
# Store Secret into Secure String - One time
# Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File C:\Scripts\RemoteConnects\GraphAPI.txt

# Retrieve Secret from the secure string
$GraphAPIClientSecret = cat C:\Scripts\RemoteConnects\GraphAPI.txt | convertto-securestring          
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($GraphAPIClientSecret)
$ClientSecret = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
#>
$loginURL       = "https://login.microsoftonline.com"                     # AAD Instance; for example https://login.microsoftonline.com
$tenantdomain   = "tenant.onmicrosoft.com"                              # AAD Tenant; for example, contoso.onmicrosoft.com
# $resource       = "https://graph.windows.net"                           # Azure AD Graph API resource URI. This is OLD
$resource       = "https://graph.microsoft.com"                           # Microsoft Graph API endpoint for All Azure Resources

# Get Universal Time. Azure AD Logs use UTC time.
$Date = Get-Date
$UTC = $Date.ToUniversalTime();
$UTC
$Time = "{0:s}" -f $UTC.AddDays(-2) + "Z"
$Time

# Create HTTP header, get an OAuth2 access token based on client id, secret and tenant domain
$body       = @{grant_type="client_credentials";resource=$resource;client_id=$ClientID;client_secret=$ClientSecret}
$oauth      = Invoke-RestMethod -Method Post -Uri $loginURL/$tenantdomain/oauth2/token?api-version=1.0 -Body $body

$AllAuditData = @()
# Autentication Headers
if ($oauth.access_token -ne $null) 
    {   
        $i=0
        $headerParams = @{'Authorization'="$($oauth.token_type) $($oauth.access_token)"}

        # Filter using days ago
        $url = 'https://graph.microsoft.com/v1.0/auditLogs/directoryAudits?$filter=activityDateTime ge ' + $Time

        Write-Host $url -ForegroundColor Red
        Do{
            $Data = Invoke-WebRequest -UseBasicParsing -Headers $headerParams -Uri $url
            $DataFromJson = $Data.Content | ConvertFrom-Json
            $ValueFromJason = $DataFromJson.value
            $AllAuditData += $ValueFromJason
            
            # Next Page of URL
            $url = $DataFromJson.'@odata.nextLink'
            $url
            $i = $i+1
          }
        while($url -ne $null)
    }
else 
    {
        Write-Host "ERROR: No Access Token"
    }
# Retrieve Data
Write-host "Activity Grouping"
Write-host "#################"
$AllAuditData | Group-Object activity

# Filter Activities to work on
$TargetData = $AllAuditData  | where{$_.activityDisplayName -like "Update user" -or $_.activityDisplayName -like "Change user license"} #|where{$_.result -like "success"}
$TargetData.Count

# Filter Activities where only License is changed
$LicenseChange = @()
foreach($item in $TargetData)
{
    if ($item | select -ExpandProperty targetresources | select -ExpandProperty modifiedProperties | where{$_.displayName -like "AssignedLicense"})
    {
    $LicenseChange += $item
    }
}
Write-Host
Write-Host "License Changed Actions: " ($LicenseChange | Measure-Object).Count
#$LicenseChange[1]

# Create a consolidated audit report for all objects for which license sku's are changed.
$AuditReport =@()
foreach($ChangedObject in $LicenseChange)
{
    # Object formating
    $Object = New-Object PSObject
    $Object | Add-Member -MemberType NoteProperty -Name ActivityDate ''
    $Object | Add-Member -MemberType NoteProperty -Name result ''
    $Object | Add-Member -MemberType NoteProperty -Name TargetUser ''
    $Object | Add-Member -MemberType NoteProperty -Name InitiatedBy ''
    $Object | Add-Member -MemberType NoteProperty -Name OldLicenseSKU ''
    $Object | Add-Member -MemberType NoteProperty -Name NewLicenseSKU ''
    $Object | Add-Member -MemberType NoteProperty -Name correlationId ''

    # Activity Date
    $AcitivityDate = [DateTime]::Parse($ChangedObject.activityDateTime)
    $Object.ActivityDate = Get-date $AcitivityDate -Format MM/dd/yyyy/hh:mm:ss

    # Activity result
    $Object.result = $ChangedObject.result

     # Activity Date
    $Object.correlationId = $ChangedObject.correlationId

    # Target & Actioned User
    $Object.TargetUser = ($ChangedObject | select -ExpandProperty targetResources).userprincipalname
    #$Object.ActionedBy = $ChangedObject.actor.userprincipalname
    $Object.InitiatedBy = ($ChangedObject.initiatedBy | select -ExpandProperty user).userPrincipalName

    # SKU Plans
    $ModifiedData = ($ChangedObject | select -ExpandProperty targetResources).modifiedProperties
    $AssignedLicense  = $ModifiedData | where{$_.displayname -like 'AssignedLicense'}

    # SKU Plans - OLD
    [string]$OSKU = @()
    if($AssignedLicense.oldValue -eq '[]')
        {$Object.OldLicenseSKU = "Null"}
    Else
        {
            #$OSKUNames = ($AssignedLicense.oldvalue -replace '[\[[,]', '').Split() | where{$_ -like '*Skuname*'}
            $OSKUNames = $AssignedLicense.oldvalue.Split('["[,[]]"')  | where{$_ -like '*Skuname*'}
            if(($OSKUNames | Measure-Object).Count -ge "1"){$OSKUNames | ForEach-Object{$OSKU += $_; $OSKU += ";"}}
            else{$Object.NewLicenseSKU = $OSKUNames  -replace ('SkuName=')}
            $Object.OldLicenseSKU = $OSKU -replace ('SkuName=')
        }
    
    # SKU Plans - New
    [string]$NSKU = @()
    if($AssignedLicense.newValue -eq '[]')
        {
            $Object.NewLicenseSKU = "Null"
        }
    Else{
            #$NSKUNames = ($AssignedLicense.newvalue -replace '[\[[,]', '').Split() | where{$_ -like '*Skuname*'}
            $NSKUNames = $AssignedLicense.newvalue.Split('["[,[]]"')  | where{$_ -like '*Skuname*'}
            if(($NSKUNames | Measure-Object).Count -ge "1"){$NSKUNames | ForEach-Object{$NSKU += $_; $NSKU += ";"}}
            else{$Object.NewLicenseSKU = $NSKUNames  -replace ('SkuName=')}
            $Object.NewLicenseSKU = $NSKU -replace ('SkuName=')
        }

    $AuditReport += $Object
}

# Add Other attributes to Audit Report
$AuditReport | Add-Member -MemberType NoteProperty "country" -Value ''
$AuditReport | Add-Member -MemberType NoteProperty "officelocation" -value ''
$AuditReport | Add-Member -MemberType NoteProperty "accountEnabled" -value ''

# Get individual user details using graph api
$TargetUsers = $AuditReport | select TargetUser -Unique
$TargetUsersDataSet = @()
foreach($user in $TargetUsers)
{
    $user.TargetUser
    $URL = 'https://graph.microsoft.com/v1.0/users/' + $user.targetuser + '?$select=userPrincipalName,displayName,postalCode,country,officelocation,AccountEnabled' #givenName
    $URL
    $Data = Invoke-WebRequest -UseBasicParsing -Headers $headerParams -Uri $url
    if(!$Data)
        {
            $URL = 'https://graph.microsoft.com/v1.0/users/' + 'hold.'+$user.targetuser + '?$select=userPrincipalName,displayName,givenName,postalCode,country,officelocation,AccountEnabled'
        }
    $DataFromJson = $Data.Content | ConvertFrom-Json
    $TargetUsersDataSet += $DataFromJson | select userPrincipalName,DisplayName, postalCode, country, officeLocation, accountEnabled
    #$AllAuditData += $ValueFromJason
}

# update audit report with target user info
foreach($item in $AuditReport)
{
    $UserFound = $TargetUsersDataSet | ?{$_.userPrincipalName -like $item.TargetUser}
    if($userfound) 
        {
            $item.country = $UserFound.country; 
            $item.officelocation = $UserFound.officelocation
            $item.accountEnabled = $UserFound.accountEnabled

        } 
}

$AuditReportSuccessCSV = New-Item AzureADLicenseAssignmentAuditReport-Success-$((Get-Date).ToString('MM-dd-yyyy')).csv -type file
$AuditReport |where{$_.result -like "success"} | Export-csv $AuditReportSuccessCSV  -NoTypeInformation

$AuditReportFailureCSV = New-Item AzureADLicenseAssignmentAuditReport-Failure-$((Get-Date).ToString('MM-dd-yyyy')).csv -type file
$AuditReport |where{$_.result -like "Failure"} | Export-csv $AuditReportFailureCSV  -NoTypeInformation

#########################
###### Send Emails ######
#########################

    $MailSubject1 = "Azure AD License Assignment Audit Report for last 2 days - From Graph API"
    #$MailBody1 = $VaultDetails | ConvertTo-Html -Head $a
    $MailBody1 = "Please find csv reports as attached."

    $MailSubjet -BodyAsHtml
    # Mailout the Report
    $smtpServer = "SMTP Server"
    $msg1 = new-object Net.Mail.MailMessage
    $smtp1 = new-object Net.Mail.SmtpClient($smtpServer)
    $attachment1 = new-object Net.Mail.Attachment($AuditReportSuccessCSV)
    $attachment2 = new-object Net.Mail.Attachment($AuditReportFailureCSV)

    $msg1.From = "AzureADLicenseAssignmentAudit@tenant.com"
    $msg1.To.Add("Email ID")
    $msg1.To.Add("Email ID")
    $msg1.Subject = $MailSubject1
    $msg1.Body = $MailBody1
    $msg1.Attachments.Add($attachment1)
    $msg1.Attachments.Add($attachment2)
    $msg1.IsBodyHTML=1
    $smtp1.Send($msg1)

Posted in Mix & Match | Tagged: , , , , | 2 Comments »

Retrieve Mailbox Permissions for Mass Users – Powershell

Posted by Brajesh Panda on February 25, 2020

# Author: Brajesh Ranjan Panda
# Blog:  https://technotip.wordpress.com
# Retrieves mailbox permissions for a set of users
# Last update: Feb 25, 2020
# Each permission will have it's own row and will have below outputs
# Mailbox, UserPrincipalName,RecipientTypeDetails,Office,User,AccessRights,MailboxAccountStatus,UserAccountStatus,UserRecipientType

# Connect Office 365
.\Connect-RemoteOff365PowerShell.ps1

# Get List of Mailboxes

# $AllMailboxes = Get-Mailbox -ResultSize 10000 | ?{$_.PrimarySMTPAddress -notlike "DiscoverySearchMailbox*"}
# $AllMailboxes = Get-RemoteMailbox -OnPremisesOrganizationalUnit "OU/OU/Users" -ResultSize unlimited
# $AllMailboxes = Import-Csv C:\Users\User\Desktop\Mailboxes.csv
$AllMailboxes = Get-DistributionGroupMember -Identity "group@domain.com" -ResultSize unlimited
$AllMailboxes.Count

# Emptry Array to store data
$allperms = @()

$i = 0
foreach($Item in $AllMailboxes)
{
    $i
    $i++
    # Optional Get-Mailbox, use it when you are importing list of target boxes from CSV, from Distribution Group or OnPremOU
    $MBX = Get-Mailbox $Item.PrimarySMTPAddress

    # Retreive Permissions
    $Permissions = Get-MailboxPermission -Identity $MBX.PrimarySMTPAddress | `
                   where { ($_.IsInherited -eq $false) -and -not ($_.User -like "NT AUTHORITY\SELF") -and -not ($_.User -like "S-1-*")} | `
                   select @{n="Mailbox";e={$MBX.PrimarySMTPAddress}},@{n="UserPrincipalName";e={$MBX.WindowsLiveID}},@{n="RecipientTypeDetails";e={$MBX.RecipientTypeDetails}}, `
                   @{n="Office";e={$MBX.Office}},User, @{n="AccessRights";e={$_.AccessRights -join ';'}} #, IsInherited, Deny
    if($Permissions){$allperms += $Permissions}

    # OnBehalf Access
    if($MBX.GrantSendOnBehalfTo)
    
        {
            foreach($item in $MBX.GrantSendOnBehalfTo)
            {
                 $item
                 $hash = @{            
                             Mailbox       = $MBX.PrimarySmtpAddress
                             UserPrincipalName   = $MBX.WindowsLiveID
                             RecipientTypeDetails   = $MBX.RecipientTypeDetails
                             Office   = $MBX.Office
                             User          = (Get-User $item).UserPrincipalName              
                             AccessRights  = 'GrantSendOnBehalfTo'            
                             #IsInherited   = ''
                             #Deny          = ''
                           }
                if($hash){$Object = New-Object PSObject -Property $hash}
                $MBX.PrimarySmtpAddress
                $Object
                if($Object){ $allperms += $Object}
                Remove-Variable Object
                Remove-Variable hash
              }
       }
    # Send As Access
    $SendAs = Get-RecipientPermission  -Identity $MBX.PrimarySMTPAddress  | `
                    ?{($_.Trustee -notlike "NT AUTHORITY\SELF")  -and -not ($_.Trustee -like "S-1-*") -and -not ($_.Trustee -like "NULL SID")} | `
                    select @{n="Mailbox";e={$MBX.PrimarySMTPAddress}}, @{n="UserPrincipalName";e={$MBX.WindowsLiveID}}, @{n="RecipientTypeDetails";e={$MBX.RecipientTypeDetails}}, `
                   @{n="Office";e={$MBX.Office}}, @{n="User";e={$_.Trustee}}, @{n="AccessRights";e={$_.AccessRights -join ';'}}
    if($SendAs){$allperms += $SendAs}
    Remove-Variable SendAs
}

#$allperms | export-csv C:\Users\User\Desktop\mailbox_perms1.csv -NoTypeInformation

# Get More Info about account status
$allperms | Add-Member -MemberType NoteProperty -Name MailboxAccountStatus ''
$allperms | Add-Member -MemberType NoteProperty -Name UserAccountStatus ''
$allperms | Add-Member -MemberType NoteProperty -Name UserRecipientType ''

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
.\Connect-WindowsAzureOnline.ps1
$liveids = $allperms | select-Object UserPrincipalName -Unique

# Get Mailbox's Account Status
foreach($id in $liveids)
{
    try {
            $Account = Get-MsolUser -UserPrincipalName $id.UserPrincipalName -ErrorAction Stop
            if($Account.BlockCredential -like 'False') {$blockcredential = "MSol Account Enabled"}
            else {$blockcredential = "MSol Account Disabled"}

        }
    catch{
            $blockcredential = 'can not find'
         }
    $allperms | ?{$_.UserPrincipalName -like $Id.UserPrincipalName} | ForEach-Object{ $_.MailboxAccountStatus = $blockcredential}
}

# Get target user (permission holders) Account Status
$UserIds = $allperms | select-Object user -Unique
foreach($id in $UserIds)
{
    try {
            $Account = Get-MsolUser -UserPrincipalName $id.user -ErrorAction Stop
            if($Account.BlockCredential -like 'False') {$blockcredential = "MSol Account Enabled"}
            else {$blockcredential = "MSol Account Disabled"}
        }
    catch{
            $blockcredential = 'can not find'
         }
    $allperms | ?{$_.user -like $Id.user} | ForEach-Object{ $_.UserAccountStatus = $blockcredential}
}

# Get target user (permission holders) recpient Status
$UserIds = $allperms | select-Object user -Unique
foreach($id in $UserIds)
{
    try {
            $Recipient = Get-Recipient  $id.user -ErrorAction Stop
            $RecipientTypeDetails = $Recipient.RecipientTypeDetails
        }
    catch{
            $RecipientTypeDetails = 'can not find'
         }
    $allperms | ?{$_.user -like $Id.user} | ForEach-Object{ $_.UserRecipientType = $RecipientTypeDetails}
}


$allperms | export-csv C:\Users\User\Desktop\mailbox_perms2.csv -NoTypeInformation

Posted in Mix & Match | Leave a Comment »

Azure Web App & SSL Certificate Reporting using Powershell

Posted by Brajesh Panda on February 18, 2019

Here you go… download from here.

Still using AzureRM Module. But can be easily converted to Az Module

# Retrieve Azure Web App and Azure Certificate Details.
# Helps to find out which Web Apps are enabled for TLS 1.0 or 1.1 so they can be moved to 1.2
# Helps to find out few other info like if HttpsOnly is enabled, Tags, Cert Thumbprint and Expiry date
# Generates CSV files

Connect-AzureRmAccount
#Select-AzureRmSubscription -Subscription "test"

# Pick all subscriptions except Azure AD
$AllSubscription = Get-AzureRmSubscription | ?{$_.name -inotlike "*Azure Active Directory"}

# Few empty arrays
$AllSSLCerts = @()
$AllWebApps = @()

# Retrieve required info from each subscription
foreach($Subscription in $AllSubscription)
{
    $Subscription.Name
    $null = Select-AzureRmSubscription -SubscriptionId $Subscription.ID

    # Web App SSL Certificates
    $WebAppCerts = Get-AzureRmWebAppCertificate 
    $AllWebAppCerts =  $WebAppCerts | select @{n="SubscriptionName";e={$Subscription.Name}}, FriendlyName, IssueDate, ExpirationDate, `
                                                         Thumbprint, SubjectName,Location, Issuer, @{n="ResourceType";e={$_.Type}}
       
    # Get Azure Web Apps
    $WebApps = Get-AzureRmWebApp

    # Retreive all Key Value paris from Tags & put them into new attributes i.e. Tag-'Key
    $AllKyes = @()
    foreach($item in $WebApps)
        {
            $AllKyes += $item.Tags.Keys
        }
    $SelectedKeys = $AllKyes | select -Unique | ?{$_ -notlike "hidden*"}
    foreach($key in $SelectedKeys)
        {
            $TagAttribute = "Tag-"+$key
            $WebApps | Add-Member -MemberType NoteProperty -Name $TagAttribute -Value '' -Force

            foreach($item in $WebApps)
                {
                    $Object  = New-Object PSObject -Property $item.tags
                    $item.$TagAttribute = $Object.$key
                }
        }

    # Select Specific Attributes from web apps
    $WebAppsDetails = $WebApps| select @{n="SubscriptionName";e={$Subscription.Name}}, Name, State, Enabled, ResourceGroup, Location, DefaultHostName, Tag-*, httpsOnly, `
                            #@{n="httpsOnly";e={(Get-AzureRmResource -ResourceGroupName $_.ResourceGroup  -ResourceType Microsoft.Web/sites -ResourceName $_.name -ApiVersion 2016-08-01).Properties.httpsOnly}},`    
                            @{n="minTLSVersion";e={(Get-AzureRmResource -ResourceGroupName $_.ResourceGroup  -ResourceType Microsoft.Web/sites/config -ResourceName $_.name -ApiVersion 2016-08-01).Properties.minTLSVersion}},`
                            @{n="CertName";e={(Get-AzureRmWebAppSSLBinding -WebAppName $_.Name -ResourceGroupName $_.ResourceGroup).Name}}, `
                            @{n="Thumbprint";e={(Get-AzureRmWebAppSSLBinding -WebAppName $_.Name -ResourceGroupName $_.ResourceGroup).Thumbprint}}, `
                            SubjectName,ExpirationDate, Issuer

    # find out ExpiryDate, SubjectNames, Issuer Name
    foreach($WebApp in $WebAppsDetails)
    {
        if($WebApp.Thumbprint){
            $Cert = $AllWebAppCerts |?{$_.Thumbprint -eq $WebApp.Thumbprint}
            $WebApp.ExpirationDate = $cert.ExpirationDate
            $WebApp.SubjectName = $cert.SubjectName
            $WebApp.Issuer = $cert.Issuer
                }
    }

    $AllSSLCerts += $AllWebAppCerts | sort expirationdate
    $AllWebApps += $WebAppsDetails
    Remove-Variable -Name AllWebAppCerts
    Remove-Variable -Name WebAppsDetails
    Remove-Variable -Name WebAppCerts
    Remove-Variable -Name WebApps
}
$AllSSLCerts | Export-Clixml C:\Scripts\AllSSLCerts2.xml
$AllWebApps | Export-Clixml C:\Scripts\AllWebApps2.xml

$AllSSLCerts | Export-Csv C:\Scripts\AllSSLCerts2.csv -NoTypeInformation
$AllWebApps | Export-Csv C:\Scripts\AllWebApps2.csv -NoTypeInformation

Posted in Powershell | 3 Comments »

Uptime Downtime

Posted by Brajesh Panda on February 18, 2019

Posted in Mix & Match | Leave a Comment »

Powershell: Check if the current logged on account is Admin or not.

Posted by Brajesh Panda on December 10, 2018

$Identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$Principal = New-Object System.Security.Principal.WindowsPrincipal($Identity)
$IsAdmin = $Principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
$IsAdmin

If UAC is enabled it will show False.

Posted in Mix & Match, Powershell | Tagged: | Leave a Comment »

Office 365 Autodiscover

Posted by Brajesh Panda on September 22, 2018

One of the best article I have ever read.

https://blogs.technet.microsoft.com/rmilne/2015/04/29/office-365-autodiscover-lookup-process/

 

Posted in Mix & Match | Leave a Comment »