One Bastion to access them all (All peered vNets)


azure

Until now, Azure Bastion has been restricted to use within the one vNet where it is connected.
It could not work across vNet peerings or vNets connected to Virtual VAN’s.
If you wanted to use Bastion, you needed to create separate Bastions per vNet. Bastion with regular use comes with a cost of approximately $120/Bastion and Month, $1500/Bastion/Year. (10 vNets = $15.000)
This have now changed. Now, $1500/customer/year is enough (Well worth it!). (10 vNets = $1.500)

Bastion can now work across vNet peering!
https://docs.microsoft.com/en-us/azure/bastion/vnet-peering

Note.
If you have a virtual VAN and your vNets are connected this way, you can add peering in a hub & spoke modell to the vNet where your Bastion is located, this will allow you to use Bastion anyway without disturbing the Virtual VAN functionality.

All you have to do, is create a 2 way peering between the vNet with a Bastion, and the second vNet, and Bastion will show up in the portals ‘Connect’ dialogue.

Bastion2

Bastion1

 
References

https://docs.microsoft.com/en-us/azure/bastion/vnet-peering

 


___________________________________________________________________________________________________

Enjoy!

Regards

 Thomas Odell Balkeståhl on LinkedIn

Advertisement

Use PowerShell to clear out all local admin accounts


azure

In a true scenario, we got from a pentest report, that to many of our servers had local active accounts that were local administrators. To mitigate this, we planned to  do the following:

  • Delete all accounts except the default administrator (Disable default on 2016)
  • Rename the default to a different name
  • Set a new ‘impossible’ password that nobody knows (45chrs)
  • Leave as-is domain users in the local administrators group

Simple enough if done on one server, via the Windows GUI…but given the circumstanses, having about 100 Windows servers, we decided to do it using PowerShell and to run the script from the Azure portals ‘Run command’ feature (Recommended). Both can however also be used locally on the servers.
What differs in the two versions are, if the servers are running 2016 or later, or 2012R2 or earlier. We had both so we needed two scripts.
(Apologies for the bad formatting in this blog-template)

Windows Server 2016 and later:

# Delete all local admin but default, rename it to Osadmin and reset pwd to 45 chrs random string
$NewAdminName = "OSAdmin"
$Admins = Get-LocalGroupMember -Group 'Administrators' | Select-Object ObjectClass, Name, PrincipalSource | Where-Object {$_.PrincipalSource -eq "Local"} | Select-Object Name
$DefaultAdmin = (Get-WmiObject Win32_UserAccount -filter "LocalAccount=True" | ? {$_.SID -like "S-1-5-21-*-500"}).Name
foreach($Admin in $Admins) {
$UserName = ($Admin.Name).ToString().split("\")[1]
Disable-LocalUser $UserName
If ($UserName -ne $DefaultAdmin) {
Remove-LocalUser $UserName
Write-Host "Removed Admin: $UserName"
}
else {
$Random = ConvertTo-SecureString ((1..45 | ForEach-Object {('abcdefghiklmnoprstuvwxyzABCDEFGHKLMNOPRSTUVWXYZ1234567890!"§$%&/()=?}][{@#*+')[(Get-Random -Maximum ('abcdefghiklmnoprstuvwxyzABCDEFGHKLMNOPRSTUVWXYZ1234567890!"§$%&/()=?}][{@#*+').length)]}) -join "") -AsPlainText -Force
Set-LocalUser -Name $DefaultAdmin -Password $Random
Write-Host "Default Admin password reset to 45 chrs long random string"
if ($DefaultAdmin -ne $NewAdminName){
Rename-LocalUser -Name $DefaultAdmin -NewName $NewAdminName
Write-Host "Renamed default Admin: $UserName to $NewAdminName"
}
}
}
Write-host "Done - Server secured :-)"
 
– – – – – – – – – – – – – – – – – – – –
Pre Windows Server 2016:
 
# Delete all local admin but default, rename it to Osadmin and reset pwd to 45 chrs random string
$NewAdminName = "OSAdmin"
$LocalAdmins = (get-wmiobject -ComputerName $Env:Computername win32_group -filter "name='Administrators' AND LocalAccount='True'").GetRelated("win32_useraccount")

foreach ($LocalUser in $LocalAdmins){
$UserName = $LocalUser.Name
$UserSID = $LocalUser.SID
$userDomain = $LocalUser.Domain
if ($LocalUser.Domain -eq $Env:Computername)
{

If ($userSID -like "S-1-5-21-*-500"){
Write-Host "OK Default: $userName $userDomain" -ForegroundColor Green
If ($UserName -ne $NewAdminName){
$LocalUser.Rename($NewAdminName)
}

$Random = (1..45 | ForEach-Object {('abcdefghiklmnoprstuvwxyzABCDEFGHKLMNOPRSTUVWXYZ1234567890!"§$%&/()=?}][{@#*+')[(Get-Random -Maximum ('abcdefghiklmnoprstuvwxyzABCDEFGHKLMNOPRSTUVWXYZ1234567890!"§$%&/()=?}][{@#*+').length)]}) -join ""
[adsi]$User = "WinNT://./$NewAdminName,user"
$User.SetPassword($Random)
$User.SetInfo()
}
else {Write-Host "DELETE: $userName $userDomain" -ForegroundColor Red
[ADSI]$server = "WinNT://$Env:computername"
$server.delete("user",$UserName)
}
}
else {Write-Host "OK Domain: $userName $userDomain" -ForegroundColor Green}
}
 
Happy PowerShell scripting!
 

References
Not this one


___________________________________________________________________________________________________

Enjoy!

Regards

 Thomas Odell Balkeståhl on LinkedIn

Use PowerShell to Add ACL, permission or Role assignment on all objects in all subscriptions


azure

The following script is made for those of you who has many subscriptions, or many objects, and you want to do something with them…
In my case, I needed to add the DBA’s AAD Group as Reader to all the disks of the SQL Server VM’s. Migrated servers, 6 disks each…you do not want to do that manually in the portal…

Run it a PowerShell tool of choice, prompt from script, ISE, VS Code or in CloudShell.
! However, there is a verified bug in a Az module used by New-AzRoleAssignment, tested and verified to work in CloudShell with Az module az.resources 2.5.1

  • Get-AzDisk can be replaced with Get-AzXXX to get any type of object you need.
  • New-AzRoleAssignment can be replaced with just about anything you want to do to the objects.
# Adds a Role assignment(ACL/RBAC) on all disks in all subscriptions based on strings in disks names
# In this example, the AAD Group ‘AAD-Group’ is added as Reader on all disks in all subscriptions, where the disks name contains the keywords: VM1, VM2 or SQL1
 
$Group = Get-AzADGroup -SearchString “AAD-Group”
$MySubs = Get-AzSubscription
Foreach ($Sub in $MySubs){
    Write-host $Sub.name
    Select-AzSubscription $sub.Name
    $Disks = Get-AzDisk | Where-Object { $_.Name -match ‘VM1’ -or $_.Name -match ‘VM2’ -or $_.Name -match ‘SQL1’}

    ForEach ($Disk in $Disks){
        Write-Host $Disk.name
        # Reader, Contributor, Owner, etc.
        New-AzRoleAssignment  -ObjectId $Group.Id -RoleDefinitionName ‘Reader’ -ResourceName $Disk.Name -ResourceGroupName $Disk.ResourceGroupName -ResourceType $Disk.Type
    }
}
 
– – – – – – – – – – – – – – – – – – – –
 
# Adds a Role assignment(ACL/RBAC) on all recovery vaults in all subscriptions
# In this example, the AAD Group ‘AAD-Group’ is added as Reader on all Recovery vaults in all subscriptions.
$Group = Get-AzADGroup -SearchString “AAD-Group”
$MySUbs = Get-AzSubscription # Get-AzSubscription
#Write-Output $MySubs
Foreach ($Sub in $MySubs){
    Write-host $Sub.name
    Select-AzSubscription $sub.Name
    $Vaults = Get-AzRecoveryServicesVault

    ForEach ($Vault in $Vaults){
        Write-Host $Vault.name
        # Reader, Contributor, Owner, etc.
        New-AzRoleAssignment  -ObjectId $Group.Id -RoleDefinitionName ‘Reader’ -ResourceName $Vault.Name -ResourceGroupName $Vault.ResourceGroupName -ResourceType $Vault.Type
    }
}
 
Happy PowerShell scripting!
 

References
https://docs.microsoft.com/en-us/powershell/azure/install-az-ps


___________________________________________________________________________________________________

Enjoy!

Regards

 Thomas Odell Balkeståhl on LinkedIn