Powershell script to get Vnet/subnet,tls version and Private endpoint in an azure webapp - azure-web-app-service

I'm using the below script:
Powershell script to get only specific Fields in an azure webapp
But that appears not to complete the requirement.

Below is the script that worked for me.
$PrivateEndPoints = Get-AzPrivateEndpoint
$Result=#()
For($I=0;$I -lt $PrivateEndPoints.count;$I++) {
$PrivateLinkServiceId = $PrivateEndPoints[$I].PrivateLinkServiceConnections.PrivateLinkServiceId
$SubnetId = $PrivateEndPoints[$I].Subnet.Id
$WebAppArray = $PrivateEndPoints[$I].PrivateLinkServiceConnections.PrivateLinkServiceId.ToLower() -split "/"
$SubnetArray = $SubnetId -split "/"
if(($WebAppArray -like "*Microsoft.Web*") -and ($SubnetId -like "*virtualNetworks*"))
{
For($J=0;$J -lt $SubnetArray.count;$J++){
$SubnetNameIndex = $SubnetArray.indexOf("subnets") + 1
$SubnetName = $SubnetArray[$SubnetNameIndex]
}
For($J=0;$J -lt $SubnetArray.count;$J++){
$VnetNameIndex = $SubnetArray.indexOf("virtualNetworks") + 1
$VnetName = $SubnetArray[$VnetNameIndex]
}
For($J=0;$J -lt $WebAppArray.count;$J++){
$WebAppNameIndex = $WebAppArray.indexOf("sites") + 1
$WebAppName = $WebAppArray[$WebAppNameIndex]
}
$obj = [PSCustomObject]#{
WebAppName = $WebAppName
PrivateEndpointName = $PrivateEndPoints[$I].Name
VnetName = $VnetName
Subnets = $SubnetName
}
$Result+=$obj
}
}
$Result
RESULTS:

Related

Add exceptions for file paths from azure defender to adaptive application security controls

I have a bunch of machines being monitored by adaptive application security controls that are giving warnings because the training process was not ran long enough to recognize benign executables. What's an easy way to add exceptions for the executables in active alerts to the adaptive security groups?
There's already an existing recommendation that might provide what you are trying to do:
https://learn.microsoft.com/en-us/azure/defender-for-cloud/adaptive-application-controls#respond-to-the-allowlist-rules-in-your-adaptive-application-control-policy-should-be-updated-recommendation
This script grabs the active alerts from defender, and updates the groups.
The alerts must still be dismissed manually.
function Get-ExistingRules {
Param(
$subscriptionId,
$groupName
)
$url = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Security/locations/centralus/applicationWhitelistings/${groupName}?api-version=2015-06-01-preview";
return az rest `
--method get `
--url $url `
| ConvertFrom-Json;
}
function Add-NewRules {
Param(
$subscriptionId,
$groupName,
$files
)
$url = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Security/locations/centralus/applicationWhitelistings/${groupName}?api-version=2015-06-01-preview";
$existing = Get-ExistingRules $subscriptionId $groupName;
$existing | ConvertTo-Json -Depth 100 > asd.json;
$myList = $existing.properties.pathRecommendations;
foreach ($file in $files) {
$myList += [pscustomobject]#{
path = $file.path
type = "File"
common = $true
action = "Add"
usernames = #(
[pscustomobject]#{
username = "Everyone"
recommendationAction = "Recommended"
}
)
userSids = #(
"S-1-1-0"
)
fileType = $file.type
configurationStatus = "NotConfigured"
};
}
$existing.properties.pathRecommendations = $myList;
$existing.properties = [pscustomobject]#{
protectionMode = $existing.properties.protectionMode
vmRecommendations = $existing.properties.vmRecommendations
pathRecommendations = $existing.properties.pathRecommendations
}
$existing.PSObject.properties.remove("location");
# return $existing;
$body = $existing | ConvertTo-Json -Depth 20 -Compress;
$body > temp.json;
# $body = $body -replace "`"", "\`"";
# return az rest `
# --method PUT `
# --url $url `
# --body $body `
# | ConvertFrom-Json;
# avoid max command length limit by storing body in a file
try {
return az rest `
--method PUT `
--url $url `
--body `#temp.json `
| ConvertFrom-Json;
}
catch {
Write-Warning "Encountered error adding rule";
Write-Warning "$_";
}
return $null;
}
function Format-Body {
param(
$obj
)
$body = $obj | ConvertTo-Json -Depth 100 -Compress;
$body = $body -replace "`"", "\`"";
$body = $body -replace "`r", "";
return $body;
}
Write-Host "Listing subscriptions";
# you can filter to just one subscription if you want
# $subscriptions = az account list --query "[?name=='NPRD'].id" --output tsv;
$subscriptions = az account list --query "[].id" --output tsv;
$allAlerts = New-Object System.Collections.ArrayList;
$i = 0;
foreach ($sub in $subscriptions) {
Write-Progress -Id 0 -Activity "Fetching alerts" -Status $sub -PercentComplete ($i / $subscriptions.Count * 100);
$i = $i++;
$alerts = az security alert list `
--subscription $sub `
| ConvertFrom-Json `
| Where-Object { #("VM_AdaptiveApplicationControlLinuxViolationAudited", "VM_AdaptiveApplicationControlWindowsViolationAudited") -contains $_.alertType } `
| Where-Object { $_.status -eq "Active" };
foreach ($x in $alerts) {
$allAlerts.Add($x) > $null;
}
}
Write-Progress -Id 0 "Done" -Completed;
function Get-Files {
Param(
$alert
)
if ($alert.alertType -eq "VM_AdaptiveApplicationControlLinuxViolationAudited") {
$fileType = "executable";
}
else {
$fileType = "exe";
}
$pattern = "Path: (.*?);";
$str = $alert.extendedProperties.file;
return $str `
| Select-String -Pattern $pattern -AllMatches `
| ForEach-Object { $_.Matches } `
| ForEach-Object { $_.Value } `
| ForEach-Object { [pscustomobject]#{
path = $_
type = $fileType
}};
}
$alertGroups = $allAlerts | Select-Object *, #{Name = "groupName"; Expression = { $_.extendedProperties.groupName } } | Group-Object groupName;
foreach ($group in $alertGroups) {
$groupName = $group.Name;
$group.Group[0].id -match "/subscriptions/([^/]+)/" > $null;
$subscriptionId = $matches[1];
$files = $group.Group | ForEach-Object { Get-Files $_ };
Write-Host "Adding file path rule sub=$subscriptionId group=$groupName count=$($files.Count)";
Add-NewRules $subscriptionId $groupName $files;
}

How to pull all tags at resource level in azure

I am Trying to pull All the Tags resource level in azure
$subscripionList = Get-AzSubscription
foreach ($subscriptionId in $subscripionList) {
Write-Host 'Getting details about SubscriptionId :' $subscriptionId
Set-AzContext -Subscription $subscriptionId
#Select-AzureRmSubscription -SubscriptionName $subscriptionId
$resourcesgroups = Get-AzResourceGroup
foreach($resourcesgroup in $resourcesgroups){
Write-Host 'resourcegroup :' $resourcesgroup
$resources = Get-AzResource -ResourceGroupName $resourcesgroup.ResourceGroupName
#$azure_resources = Get-AzResource
foreach($resource in $resources){
Write-Host $resource
{
#Fetching Tags
$Tags = $resource.Tags
#Checkign if tags is null or have value
if($Tags -ne $null)
{
foreach($Tag in $Tags)
{
$TagsAsString += $Tag.Name + ":" + $Tag.Value + ";"
}
}
else
{
$TagsAsString = "NULL"
}
}
}
}
I am Trying to get all the subscription then
I am Trying to get all the resource groups then
I am Trying to get all the resource present in resource group
Trying to get all the tags
But i am unable to get Tags and can anyone guide me how to export all tags into csv file.
As there is no $tag.Name and $Tag.Value , Your code doesn't store any values. The output you are looking are stored as $tags.keys and $tags.values. So, to collect them you will have to use for loop again . I tested the same by replacing the for each loop for the resources with the below script:
$TagsAsString=#()
$tagkeys =#()
$TagValues =#()
$resources = Get-AzResource -ResourceGroupName <resourcegroupname>
foreach($resource in $resources){
Write-host ("ResourceName :")$resource.Name
if($resource.Tags -ne $null){
foreach($Tag in $resource.Tags){
foreach($key in $Tag.keys){
$tagkeys += $key
}
foreach($value in $Tag.values){
$TagValues += $value
}
}
}
else{
Write-Host ("No Tags")
}
}
for($i = 0; $i -lt $tagkeys.Length; $i++) {
$TagsAsString=( '{0} : {1}' -f $tagkeys[$i], $tagvalues[$i] )
Write-Host $TagsAsString
}
Output:

Assistance with looping through multiple subscriptions

I'm using the below script from http://vcloud-lab.com/entries/microsoft-azure/get-azure-virtual-machine-backup-reports-using-powershell to pull Azure VM backup details. Currently I have to run the script against each subscription, I would love to have it loop though all subscriptions.
I've been trying to get it working using this example https://www.jpaul.me/2019/05/azure-automation-how-to-quickly-work-with-many-subscriptions/ but I'm new to powershell and am struggling. Any suggestions would be really appreciated.
[CmdletBinding(SupportsShouldProcess=$True,
ConfirmImpact='Medium',
HelpURI='http://vcloud-lab.com',
DefaultParameterSetName = 'AllVirtualMachines'
)]
<#
.SYNOPSIS
Collect Azure VM Backup Information
.DESCRIPTION
This Script collects Azure Virtual Machine Backup Recovery service vault information, This report includes the complete backup status Information of VM.
.PARAMETER AllVirtualMachines
Collect Backup information of the all Azure Virtual Machines, This is default parameter.
.PARAMETER VirtualMachineList
You can specify for which virtual machine you want backup information.
.INPUTS
None. Provides virtual machine information.
.OUTPUTS
Generate Backup information. You can pipe information to Export-CSV.
.EXAMPLE
PS> .\Get-AzVMBackupInformation.ps1
VM_Name : vcloud-lab-vm01
VM_Location : uksouth
VM_ResourceGroupName : VCLOUD-LAB.COM
VM_BackedUp : True
VM_RecoveryVaultName : vault828
VM_RecoveryVaultPolicy : DailyPolicy-kosrnox0
VM_BackupHealthStatus : Passed
VM_BackupProtectionStatus : Healthy
VM_LastBackupStatus : Completed
VM_LastBackupTime : 27-05-2021 19:32:34
VM_BackupDeleteState : NotDeleted
VM_BackupLatestRecoveryPoint : 27-05-2021 19:32:37
VM_Id : /subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/VCLOUD-LAB.COM/providers/Microsoft.Compute/virtualMachines/vcloud-lab-vm01
RecoveryVault_ResourceGroupName : vCloud-lab.com
RecoveryVault_Location : uksouth
RecoveryVault_SubscriptionId : /subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vCloud-lab.com/providers/Microsoft.RecoveryServices/vaults/vault828
.EXAMPLE
PS> .\Get-AzVMBackupInformation.ps1 -AllVirtualMachines
This produces same result as .\Get-AzVMBackupInformation.ps1 from all VMs
.EXAMPLE
PS> .\Get-AzVMBackupInformation.ps1 -VirtualMachineList
Provide either single virtual machine name or in list
.LINK
Online version: http://vcloud-lab.com
.LINK
Get-AzVMBackupInformation.ps1
#>
Param
(
[parameter(Position=0, ParameterSetName = 'AllVMs' )]
[Switch]$AllVirtualMachines,
[parameter(Position=0, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True, ParameterSetName = 'VM' )]
[alias('Name')]
[String[]]$VirtualMachineList
) #Param
Begin
{
#Collecing Azure virtual machines Information
Write-Host "Collecing Azure virtual machine Information" -BackgroundColor DarkGreen
if (($PSBoundParameters.ContainsKey('AllVirtualMachines')) -or ($PSBoundParameters.Count -eq 0))
{
$vms = Get-AzVM
} #if ($PSBoundParameters.ContainsKey('AllVirtualMachines'))
elseif ($PSBoundParameters.ContainsKey('VirtualMachineList'))
{
$vms = #()
foreach ($vmname in $VirtualMachineList)
{
$vms += Get-AzVM -Name $vmname
} #foreach ($vmname in $VirtualMachineList)
} #elseif ($PSBoundParameters.ContainsKey('VirtualMachineList'))
#Collecing All Azure backup recovery vaults Information
Write-Host "Collecting all Backup Recovery Vault information" -BackgroundColor DarkGreen
$backupVaults = Get-AzRecoveryServicesVault
} #Begin
Process
{
$vmBackupReport = [System.Collections.ArrayList]::new()
foreach ($vm in $vms)
{
$recoveryVaultInfo = Get-AzRecoveryServicesBackupStatus -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName -Type 'AzureVM'
if ($recoveryVaultInfo.BackedUp -eq $true)
{
Write-Host "$($vm.Name) - BackedUp : Yes"
#Backup Recovery Vault Information
$vmBackupVault = $backupVaults | Where-Object {$_.ID -eq $recoveryVaultInfo.VaultId}
#Backup recovery Vault policy Information
$container = Get-AzRecoveryServicesBackupContainer -ContainerType AzureVM -VaultId $vmBackupVault.ID -FriendlyName $vm.Name #-Status "Registered"
$backupItem = Get-AzRecoveryServicesBackupItem -Container $container -WorkloadType AzureVM -VaultId $vmBackupVault.ID
} #if ($recoveryVaultInfo.BackedUp -eq $true)
else
{
Write-Host "$($vm.Name) - BackedUp : No" -BackgroundColor DarkRed
$vmBackupVault = $null
$container = $null
$backupItem = $null
} #else if ($recoveryVaultInfo.BackedUp -eq $true)
[void]$vmBackupReport.Add([PSCustomObject]#{
VM_Name = $vm.Name
VM_Location = $vm.Location
VM_ResourceGroupName = $vm.ResourceGroupName
VM_BackedUp = $recoveryVaultInfo.BackedUp
VM_RecoveryVaultName = $vmBackupVault.Name
VM_RecoveryVaultPolicy = $backupItem.ProtectionPolicyName
VM_BackupHealthStatus = $backupItem.HealthStatus
VM_BackupProtectionStatus = $backupItem.ProtectionStatus
VM_LastBackupStatus = $backupItem.LastBackupStatus
VM_LastBackupTime = $backupItem.LastBackupTime
VM_BackupDeleteState = $backupItem.DeleteState
VM_BackupLatestRecoveryPoint = $backupItem.LatestRecoveryPoint
VM_Id = $vm.Id
RecoveryVault_ResourceGroupName = $vmBackupVault.ResourceGroupName
RecoveryVault_Location = $vmBackupVault.Location
RecoveryVault_SubscriptionId = $vmBackupVault.ID
}) #[void]$vmBackupReport.Add([PSCustomObject]#{
} #foreach ($vm in $vms)
} #Process
end
{
$vmBackupReport
} #end
You can try this sample script from the MS doc for looping through multiple subscriptions.
Connect-AzAccount
$SubscriptionList = Get-AzSubscription
foreach ($Id in $SubscriptionList)
{
#Provide the subscription Id where the VMs reside
$subscriptionId = $Id
#Provide the name of the csv file to be exported
$reportName = "myReport.csv"
Select-AzSubscription $subscriptionId
$report = #()
$vms = Get-AzVM
$publicIps = Get-AzPublicIpAddress
$nics = Get-AzNetworkInterface | ?{ $_.VirtualMachine -NE $null}
foreach ($nic in $nics)
{
$info = "" | Select VmName, ResourceGroupName, Region, VmSize, VirtualNetwork, Subnet, PrivateIpAddress, OsType, PublicIPAddress, NicName, ApplicationSecurityGroup, subscriptionId
$vm = $vms | ? -Property Id -eq $nic.VirtualMachine.id
foreach($publicIp in $publicIps)
{
if($nic.IpConfigurations.id -eq $publicIp.ipconfiguration.Id)
{
$info.PublicIPAddress = $publicIp.ipaddress
}
}
$info.subscriptionId = $subscriptionId
$info.OsType = $vm.StorageProfile.OsDisk.OsType
$info.VMName = $vm.Name
$info.ResourceGroupName = $vm.ResourceGroupName
$info.Region = $vm.Location
$info.VmSize = $vm.HardwareProfile.VmSize
$info.VirtualNetwork = $nic.IpConfigurations.subnet.Id.Split("/")[-3]
$info.Subnet = $nic.IpConfigurations.subnet.Id.Split("/")[-1]
$info.PrivateIpAddress = $nic.IpConfigurations.PrivateIpAddress
$info.NicName = $nic.Name
$info.ApplicationSecurityGroup = $nic.IpConfigurations.ApplicationSecurityGroups.Id
$report+=$info
}
$report | ft subscriptionId, VmName, ResourceGroupName, Region, VmSize, VirtualNetwork, Subnet, PrivateIpAddress, OsType, PublicIPAddress, NicName, ApplicationSecurityGroup
$report | Export-CSV "$home/$reportName"
}
References: Collect details about all VMs in a subscription with PowerShell - Azure Virtual Machines | Microsoft Docs , Iterate through subscriptions using an Array to avoid manual work · Issue #50670 · MicrosoftDocs/azure-docs · GitHub and powershell - How to loop through multiple Azure subscriptions on Azure Pipelines Yaml? - Stack Overflow

deploy Lab with windows image with azure Labservices

I try to create a lab Windows 10 or Windows Server in a lab account with PowerShell but he doesn't found any image except when I put :
Image = 'Centos-Based ' he creates a lab with centos-based 8.1
my code please :
# Create a Lab with Windows server
$la = Get-AzLabAccount -ResourceGroupName $ResourceGroupName -LabAccountName $LabAccountName
Write-Host "$LabAccountName lab account created or found."
#param (
$LabName = Read-Host ' Name of Your lab '
$Image = Read-Host ' Name of Your lab '
$Size = Read-Host ' Size of Your lab '
$InstallGpuDriverEnabled = $false
$UserName = Read-Host ' UserName of Your lab '
$Password = Read-Host ' Password of Your lab '
$UsageQuotaInHours = 10
$SharedPasswordEnabled = $false
$idleGracePeriod = 15
$idleOsGracePeriod = 0
$idleNoConnectGracePeriod = 15
$TemplateVmState = "Enabled"
#)
$img = $la | Get-AzLabAccountGalleryImage | Where-Object {$_.name -like $Image} | Select-Object -First 1
if(-not $img -or $img.Count -ne 1) {Write-Error "$Image pattern doesn't match just one image."}
Write-Host "Image $Image found."
begin { }
process {
try {
foreach ($la in $LabAccount) {
$labAccountUri = (ConvertToUri -resource $la)
$createUri = $labAccountUri + "/createLab"
$labUri = $labAccountUri + "/labs/" + $LabName
$environmentSettingUri = $labUri + "/environmentsettings/default"
$sharedPassword = if ($SharedPasswordEnabled) { "Enabled" } else { "Disabled" }
$imageType = if ($Image.id -match '/galleryimages/') { 'galleryImageResourceId' } else { 'sharedImageResourceId' }
InvokeRest -Uri $createUri -Method 'Post' -Body (#{
name = $LabName
labParameters = #{
$imageType = $Image.id
password = $Password
username = $UserName
userQuota = "PT$($UsageQuotaInHours.ToString())H"
vmSize = $Size
sharedPasswordState = $sharedPassword
templateVmState = $TemplateVmState
idleShutdownMode = $idleShutdownMode
idleGracePeriod = "PT$($idleGracePeriod.ToString())M"
enableDisconnectOnIdle = $enableDisconnectOnIdle
idleOsGracePeriod = "PT$($idleOsGracePeriod.ToString())M"
enableNoConnectShutdown = $enableNoConnectShutdown
idleNoConnectGracePeriod = "PT$($idleNoConnectGracePeriod.ToString())M"
installGpuDriverEnabled = $gpuDriverState
}
} | ConvertTo-Json) | Out-Null
}
$lab = WaitProvisioning -uri $labUri -delaySec 60 -retryCount 120
WaitProvisioning -uri $environmentSettingUri -delaySec 60 -retryCount 120 | Out-Null
return $lab
}
catch {
Write-Error -ErrorRecord $_ -EA $callerEA
}
}
end { }
$lab = $la | New-AzLab -LabName $LabName -Image $img -Size $size -UserName $userName -Password $password -UsageQuotaInHours $usageQuota | Publish-AzLab
Write-Host "$LabName lab doesn't exist. Created it."
Regarding the issue, please update the expression as Where-Object {$_.name -like "Windows 10*"}.
For exmaple
$la = Get-AzLabAccount -ResourceGroupName $ResourceGroupName -LabAccountName $LabAccountName
$img = $la | Get-AzLabAccountGalleryImage | Where-Object {$_.name -like "Windows 10*"} | Select-Object -First 1

AccessRestrictions AddIP for Multiple App Services in Azure Powershell

I have an Azure powershell script where the user has to add in the app service name, IP address and so on. I have 4 web apps where I would like to add the same IP address to. I would like to hard code the app service name so the user does not have to input it. How can I achieve this in powershell? Here is my code:
Param
(
# Name of the resource group that contains the App Service.
[Parameter(Mandatory=$true)]
$RGName,
# Name of your Web or API App.
[Parameter(Mandatory=$true)]
$WebAppName,
# priority value.
[Parameter(Mandatory=$true)]
$priority,
# WhitelistIp values.
[Parameter(Mandatory=$true)]
$IPList,
# rule to add.
[PSCustomObject]$rule
)
function Add-AzureIpRestrictionRule
{
$ApiVersions = Get-AzureRmResourceProvider -ProviderNamespace Microsoft.Web |
Select-Object -ExpandProperty ResourceTypes |
Where-Object ResourceTypeName -eq 'sites' |
Select-Object -ExpandProperty ApiVersions
$LatestApiVersion = $ApiVersions[0]
$WebAppConfig = Get-AzureRmResource -ResourceType 'Microsoft.Web/sites/config' -ResourceName $WebAppName -ResourceGroupName $RGName -ApiVersion $LatestApiVersion
$WebAppConfig.Properties.ipSecurityRestrictions = $WebAppConfig.Properties.ipSecurityRestrictions + #($rule) |
Group-Object name |
ForEach-Object { $_.Group | Select-Object -Last 1 }
Set-AzureRmResource -ResourceId $WebAppConfig.ResourceId -Properties $WebAppConfig.Properties -ApiVersion $LatestApiVersion -Force
}
$IPList= #($IPList-split ",")
Write-Host "IPList found "$IPList"."
$increment = 1
foreach ($element in $IPList)
{
if ($element -eq "" -OR $element -eq " ") {continue}
else
{
$element=$element.Trim()
$rule = [PSCustomObject]#{
ipAddress = "$($element)/32"
action = "Allow"
priority = "$priority"
name = "WhitelistIP"+ $increment}
$increment++
Add-AzureIpRestrictionRule -ResourceGroupName "$RGName" -AppServiceName "$WebAppName" -rule $rule
}
}
$OutboundIP = #(Get-AzureRmWebApp -Name "$WebAppName" -ResourceGroupName "$RGName").possibleOutboundIPAddresses -split ","
$increment = 1
foreach ($element in $OutboundIP)
{
$rule = [PSCustomObject]#{
ipAddress = "$($element)/32"
action = "Allow"
priority = "$priority"
name = "OutboundIP"+ $increment}
$increment++
Add-AzureIpRestrictionRule -ResourceGroupName "$RGName" -AppServiceName "$WebAppName" -rule $rule
}
so my $WebAppName i want it to be hard coded, but I have 4 of these web-apps, how do I get this script to run 4 times with just having the user input his IP address once, all variables stay the same, just the $WebAppName should change to the hard coded values i give
You could something like the following (If I've correctly understood the problem).
$webAppNames = 'a,b,c,d'
$webAppList = $webAppNames.split(',')
Foreach($webAppName in $webAppList) { ....do stuff }

Resources