OA_LogAnalytics.psm1


<#-----------------------------------------------------------------------------
PowerShell Module 'OA_LogAnalytics'
 
LEGAL DISCLAIMER
The sample scripts are not supported under any Microsoft standard support
program or service. The sample scripts are provided AS IS without warranty
of any kind. Microsoft further disclaims all implied warranties including,
without limitation, any implied warranties of merchantability or of fitness
for a particular purpose. The entire risk arising out of the use or
performance of the sample scripts and documentation remains with you. In no
event shall Microsoft, its authors, or anyone else involved in the creation,
production, or delivery of the scripts be liable for any damages whatsoever
(including, without limitation, damages for loss of business profits,
business interruption, loss of business information, or other pecuniary
loss) arising out of the use of or inability to use the sample scripts or
documentation, even if Microsoft has been advised of the possibility of such
damages.
-----------------------------------------------------------------------------#>


<#
.SYNOPSIS
    This module assists in the setup of Azure Log Analytic workspaces within a tenant subsctiption.
.DESCRIPTION
    This module uses simple verb-noun functions to setup: resourcegroups, add soluitions, and leverage searches to obtain Azure tenant data.
.NOTES
    Current Version : 0.9
 
    History:
            1.0 - Posted October X, 2019 - First iteration for deliveries.
 
            0.9 - September 12, 2019 - Available on PowerShellGallery for testing to other team members.
 
            0.8 - Created August 15, 2019 for creating/testing PowerShell code in verb-noun format within a module.
                - Converting PS code from Microsoft into simple verb-noun functions.
                - Testing solutions build within tenant and creating code to assist in managing those solutions.
 
.FUNCTIONALITY
   Azure tenant access is required.
   Local administrator access to client machine accessing Azure is required for PS modules to be installed.
   Azure Premium price level is the default value needed. Code can be modified to use free or basic versions. Future versions may account for the different options.
#>


#region 1. Install custom OA PS module
# Only need one of the two lines below executed to install module.
Install-Module OA_LogAnalytics -Scope CurrentUser #allows to install without elevated PS.
Install-Module OA_LogAnalytics -Force #need to run as admin in PS session

#endregion 1. Install custom OA PS module

#region 2. Ensure the Azure PS modules are installed and available.

Function Install-AzureADModules {
Install-Module az -AllowClobber -force #need to run as admin in PS session
    <# Additional online information about AZ Module:
    Start-Process https://docs.microsoft.com/en-us/powershell/azure/new-azureps-module-az?view=azps-2.6.0
    #>


Install-Module AzureAD -AllowClobber -force #need to run as admin in PS session
    <# Additional online information about AzureAD Module:
    Start-Process https://docs.microsoft.com/en-us/powershell/azure/new-azureps-module-az?view=azps-2.6.0
    #>


Install-Module -Name MSOnline -AllowClobber -Force #need to run as admin in PS session
    <# Additional online information about MSOnline Module:
    Start-Process https://www.powershellgallery.com/packages/MSOnline/
    #>


}


#endregion 2. Ensure the multiple Azure PS modules are installed and available.

#region 3. Connect to Azure. This is an MFA function, therefore needs a GUI OS to complete the prompts.

Function Connect-AzureADTenant {

Connect-AzAccount # Is cmdlet to connect to Azure via AZ module. This is an MFA cmdlet and therefore, MUST be performed on a GUI enabled host.
Connect-AzureAD # Is cmdlet to connect to Azure via AD module. This is an MFA cmdlet and therefore, MUST be performed on a GUI enabled host.
Connect-MsolService # Is cmdlet to connect to MSOL module. This is NOT an MFA enabled cmdlet by default.
}
#endregion 3. Connect to Azure. These are MFA, so needs a GUI to answer.

#region 4. Select tenant subsctipion if needed.
Function Set-AzureSubsciption {    #Select which subscription to log onto
    $AzSubscriptions = Get-AzSubscription

    For ($i=0 ; $i -lt $AzSubscriptions.Length ; $i++)
    {
        "Subscription $($i+1): $(($AzSubscriptions[$i]).name)"
    } 
    Write-Host ""
    $AzSubscriptionRequested = Read-Host "Please enter the number for the subscription needed:"
    Select-AzSubscription -Subscription ($AzSubscriptions[$AzSubscriptionRequested-1]).ID
    $AzSubscriptions[$AzSubscriptionRequested-1]
    
}

#endregion 4. Select tenant subsctipion if needed.

#region 5. Create a Log Analytics Workspace
function New-AzureLogAnalyticsWorkspace {
<#
.SYNOPSIS
   Create a new Log Anaylitics Workspace and resource group if requested.
.DESCRIPTION
   Long description
.EXAMPLE
   Example of how to use this cmdlet
.EXAMPLE
   Another example of how to use this cmdlet
.INPUTS
   Inputs to this cmdlet (if any)
.OUTPUTS
   Screen outputs for confirmation of created/updated values.
.NOTES
   General notes
.COMPONENT
   Azure Az module must be available on machine running code from.
 
   Install-Module az -AllowClobber -Scope CurrentUser #allows to install without elevated PS
   Install-Module az -AllowClobber -force #need to run as admin in PS session
 
   Import-Module az #if needed to load in module after PS has launched
 
#>

    [cmdletbinding()]
    param($ResourceGroup = "LogAnalytics-example2",
            [ValidateSet("eastasia","southeastasia","centralus","eastus","eastus2","westus","northcentralus","southcentralus","northeurope","westeurope","japanwest","japaneast","brazilsouth","australiaeast","australiasoutheast","southindia","centralindia","westindia","canadacentral","canadaeast","uksouth","ukwest","westcentralus","westus2","koreacentral","koreasouth","francecentral","francesouth","australiacentral","australiacentral2","uaecentral","uaenorthsouthafricanorth","southafricawest","germanywestcentral")]
            $Location="centralus",
            $WorkspaceName = "log-analytics-Onboarding-Accelerator2", #workspace names must be unique within the entire subscription!
            $Solutions = @("Office365", "ADReplication", "Security") # List of solutions to enable by default for delivery.
            #$Solutions = @("CapacityPerformance","AzureWebAppsAnalytics","Security","Updates","AntiMalware","LogManagement","ChangeTracking","SQLAssessment","SCOMAssessment","ServiceDesk","ADAssessment","AlertManagement","AzureAutomation","WireData","SiteRecovery","Backup","SurfaceHub","NetworkMonitoring","Containers","ContainerInsights","ServiceMap","AzureNetworking","ADReplication","Office365","CompatibilityAssessment","KeyVault","ServiceFabric","DnsAnalytics","ApplicationInsights","WireData2","WaaSUpdateInsights","AgentHealthAssessment","AzureActivity","HDInsight","HDInsightKafka","HDInsightSpark","HDInsightHadoop","AzureCdnCoreAnalytics","HDInsightStorm","HDInsightInteractiveQuery","VMware","SecurityCenterFree","LogicAppsManagement","LogicAppB2B","AzureSQLAnalytics","KeyVaultAnalytics","AzureNSGAnalytics","AzureAppGatewayAnalytics","DeviceHealthProd","WindowsDefenderATP","WindowsDefenderATPStable","InfrastructureInsights","ProcessInvestigator","Microsoft365Analytics","ASRAnalytics","SecurityInsights","SecurityCenterNetworkTraffic","WindowsFirewall","WindowsEventForwarding","InternalWindowsEvent","DHCPActivity","AzureDataFactoryAnalytics","SQLThreatDetection","AzureSecurityOfThings","SQLVulnerabilityAssessment","SQLAdvancedThreatProtection","VMInsights") # List of solutions to enable
        )

       
    $AzResourceGroups = Get-AzResourceGroup -ErrorAction SilentlyContinue
    Write-Verbose "`$AzResourceGroups array contains $($AzResourceGroups.ResourceGroupName)"
    
    For ($i=0 ; $i -lt $AzResourceGroups.Length ; $i++)
    {
        "Resource group $($i+1): $(($AzResourceGroups[$i]).ResourceGroupName)"
    } 
    
    Write-Host ""
    Write-Host "Resource group 99: Create a new resource group not listed."
    Write-Host ""
    $AzResourceGroupRequested = Read-Host "Please enter the number for the resource group option needed:"
    Write-Verbose "`$AzResourceGroupRequested value is $AzResourceGroupRequested"

    if ($AzResourceGroupRequested -eq "99") {

        # Create the resource group if needed
        try {
            Get-AzResourceGroup -Name $ResourceGroup -ErrorAction Stop
            Write-Host "The $ResourceGroup already exists, exiting RG creating process."
            Write-Host "Adding Log Analytics $($WorkspaceName) workspace to the resource group: $($ResourceGroup)."
        } catch {
            New-AzResourceGroup -Name $ResourceGroup -Location $Location
            Write-Host "Creating $ResourceGroup... "
        }
    }
    elseif ($AzResourceGroupRequested -le $AzResourceGroups.Length) {
        $ResourceGroup = $AzResourceGroups[$AzResourceGroupRequested-1].ResourceGroupName
        $Location = $AzResourceGroups[$AzResourceGroupRequested-1].Location
        Write-Host "Adding Log Analytics: $($WorkspaceName), workspace to the resource group: $($ResourceGroup)."
    }
    else {
        Write-Host ""
        Write-Host "A non-valid entry was selected. Exiting function." -ForegroundColor Red
        Write-Host ""
        exit
    }

    # Create the workspace
    New-AzOperationalInsightsWorkspace -Location $Location -Name $WorkspaceName -Sku standalone -ResourceGroupName $ResourceGroup
    
    # List all solutions and their installation status
    Get-AzOperationalInsightsIntelligencePack -ResourceGroupName $ResourceGroup -WorkspaceName $WorkspaceName
    
    # Add solutions
    foreach ($solution in $Solutions) {
        Set-AzOperationalInsightsIntelligencePack -ResourceGroupName $ResourceGroup -WorkspaceName $WorkspaceName -IntelligencePackName $solution -Enabled $true -ErrorAction SilentlyContinue
    }
    
    # List enabled/un-enabled solutions
    Write-Host "The following solutions are not enabled:" -ForegroundColor Yellow
    (Get-AzOperationalInsightsIntelligencePack -ResourceGroupName $ResourceGroup -WorkspaceName $WorkspaceName).Where({($_.enabled -eq $false)}) | Format-Table name,enabled
    Write-Host ""
    Write-Host "The following solutions are enabled:"
    (Get-AzOperationalInsightsIntelligencePack -ResourceGroupName $ResourceGroup -WorkspaceName $WorkspaceName).Where({($_.enabled -eq $true)}) | Format-Table name,enabled
    
}

#endregion 5. Create a Log Analytics Workspace

#region 6. Add Log Analytic solutions to a workspace
Function Add-AzureLogAnalyticSolutions {
[cmdletbinding()]
param ($ResourceGroup = "LogAnalytics-example",
    $WorkspaceName = "log-analytics-Onboarding-Accelerator",
    [validateset("CapacityPerformance","AzureWebAppsAnalytics","Security","Updates","AntiMalware","LogManagement","ChangeTracking","SQLAssessment","SCOMAssessment","ServiceDesk","ADAssessment","AlertManagement","AzureAutomation","WireData","SiteRecovery","Backup","SurfaceHub","NetworkMonitoring","Containers","ContainerInsights","ServiceMap","AzureNetworking","ADReplication","Office365","CompatibilityAssessment","KeyVault","ServiceFabric","DnsAnalytics","ApplicationInsights","WireData2","WaaSUpdateInsights","AgentHealthAssessment","AzureActivity","HDInsight","HDInsightKafka","HDInsightSpark","HDInsightHadoop","AzureCdnCoreAnalytics","HDInsightStorm","HDInsightInteractiveQuery","VMware","SecurityCenterFree","LogicAppsManagement","LogicAppB2B","AzureSQLAnalytics","KeyVaultAnalytics","AzureNSGAnalytics","AzureAppGatewayAnalytics","DeviceHealthProd","WindowsDefenderATP","WindowsDefenderATPStable","InfrastructureInsights","ProcessInvestigator","Microsoft365Analytics","ASRAnalytics","SecurityInsights","SecurityCenterNetworkTraffic","WindowsFirewall","WindowsEventForwarding","InternalWindowsEvent","DHCPActivity","AzureDataFactoryAnalytics","SQLThreatDetection","AzureSecurityOfThings","SQLVulnerabilityAssessment","SQLAdvancedThreatProtection","VMInsights")]
    $Solutions # Select from the valid set presented for this parameter. Can select multiples by using a comma to seperate the values. Tab complete also works when using this parameter.
    )

foreach ($solution in $Solutions) {
    Set-AzOperationalInsightsIntelligencePack -ResourceGroupName $ResourceGroup -WorkspaceName $WorkspaceName -IntelligencePackName $solution -Enabled $true -ErrorAction SilentlyContinue
    }

    Write-Host ""
    Write-Host "The following solutions are enabled for this Log Analytics workspace:"
    (Get-AzOperationalInsightsIntelligencePack -ResourceGroupName $ResourceGroup -WorkspaceName $WorkspaceName).Where({($_.enabled -eq $true)}) | Format-Table name,enabled
    
}

#endregion 6. Add Log Analytic solutions to a workspace

#region 7. Remove a selectable Resource Group if needed.

function Remove-AzureResourceGroupWithSelection {
<#
.SYNOPSIS
   Remove Azure Resource Group with a selection prompt.
.DESCRIPTION
   Remove an Azure Resource Group from the usage of a selection prompt.
   This function lists all Resource Groups within a subscription, presents the list, and allows a selection prompt to target a specific Resource Group to be removed from the current subscription.
.EXAMPLE
   Get-AzResourceGroup
   Removes an Azure Resource Group after selecting the named group from a presneted list.
.OUTPUTS
   Output to screen of values.
.NOTES
   Function created to assist speed and ease of removing Azure Resource Groups from a subsciption.
.COMPONENT
   Azure module needs to be installed and loaded into current PowerShell session in order to run this function.
#>

    [cmdletbinding()]
    param()

    #select which resource group to target
    $AzResourceGroups = Get-AzResourceGroup
    
    For ($i=0 ; $i -lt $AzResourceGroups.Length ; $i++)
    {
        "Resource group $($i+1): $(($AzResourceGroups[$i]).ResourceGroupName)"
    } 
    
    $AzResourceGroupRequested = Read-Host "Please enter the number for the resource group to remove:"
    $AzResourceGroups[$AzResourceGroupRequested-1]

Write-Verbose "`$AzResourceGroups array contains $AzResourceGroups"
Write-Host "Now removing Resource Group: "+ ($AzResourceGroups[$AzResourceGroupRequested-1]).ResourceGroupName
Remove-AzResourceGroup -Name $AzResourceGroups[$AzResourceGroupRequested-1].ResourceGroupName -Force -Confirm:$false

Write-Host ""
Write-Host "Resource Groups still available in current subscription:" -ForegroundColor Green
Get-AzResourceGroup
}

#endregion 7. Remove a selectable Resource Group if needed.

#region 8. Disconnect from PS session.
Function Disconnect-AzureADTenant {
Disconnect-AzAccount
Disconnect-AzureAD
#MSOline does not have a disconnect option.
}

#endregion 8. Disconnect from PS session.