deploy Lab with windows image with azure Labservices - azure

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

Related

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

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:

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;
}

Powershell hashtables values output Assembly not Value

Hi I'm trying to get vnet peering property using a Powershell script.
But I keep getting these values in teh table below, but when I print to screen they print fine.
These are values I keep getting:
RemoteVirtualNetwork
Microsoft.Azure.Commands.Network.Models.PSResourceId
RemoteVirtualNetworkAddressSpace
Microsoft.Azure.Commands.Network.Models.PSAddressSpace
#Login-AzAccount
$Subs = Get-AzSubscription
foreach ( $Sub in $Subs ) {
Set-AzContext -Subscription $Sub | Out-Null
$SubName = $sub.name
$vnets=get-azvirtualnetwork
foreach ($azvnet in $vnets){
$peer=get-AzVirtualNetworkPeering -VirtualNetworkName $azvnet.name -ResourceGroup $azvnet.ResourceGroupName | select-object ResourceGroupName,VirtualNetworkName,PeeringState,AllowVirtualNetworkAccess,AllowGatewayTransit,UseRemoteGateways,RemoteVirtualNetwork,RemoteVirtualNetworkAddressSpace
ForEach-Object{
New-Object PSObject -Property #{
ResourceGroupName = $peer.ResourceGroupName
VirtualNetworkName= $peer.VirtualNetworkName
PeeringState = $peer.PeeringState
PeeringSyncLevel = $peer.PeeringSyncLevel
AllowVirtualNetworkAccess = $peer.AllowVirtualNetworkAccess
AllowForwardedTraffic = $peer.AllowForwardedTraffic
AllowGatewayTransit = $peer.AllowGatewayTransit
UseRemoteGateways = $peer.UseRemoteGateways
RemoteVirtualNetwork = $peer.RemoteVirtualNetwork.Id.Split("/")[-1]
RemoteGateways = $peer.RemoteGateways
PeeredRemoteAddressSpace = $peer.PeeredRemoteAddressSpace
RemoteVirtualNetworkAddressSpace = $peer.RemoteVirtualNetworkAddressSpace | Select-Object -ExpandProperty AddressPrefixes
}
}
$peer|export-csv -path c:\personal\peers04.csv
}
}

Issue Creating SSL/TLS secure channel

The below given PowerShell Script Basically Checks for Backup Jobs inside Backup Vault and Sends a daily backup job report to emails mentioned. I am Facing issues as the script throws an error
Invoke-RestMethod : The request was aborted: Could not create SSL/TLS secure channel
I am using SendGrid Api Key in a Kv used for the mailing service. Have tried adding an updated TLS Version too it still throws the same error.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Remove-Variable -Name * -ErrorAction SilentlyContinue
$numberofdays = 2
$DAILYBACKUPSTATS = #()
$DAILYBACKUPSTATS1 = #()
$DAILYBACKUPSTATSFAILED = #()
$DAILYBACKUPSTATSFAILED1 = #()
$Subscriptions = Get-AzSubscription
$SubscriptionIDs = $Subscriptions.ID
foreach ($SubscriptionID in $SubscriptionIDs) {
$Subscription = Set-AzContext -SubscriptionId $SubscriptionID
$backupvaults = Get-AzRecoveryServicesVault
$backupvaultnames = $backupvaults.name
foreach ($backupvaultname in $backupvaultnames)
{
$backupvault = Get-AzRecoveryServicesVault -Name $backupvaultname
$startdate = [system.Datetime]::UtcNow
$enddate = ([system.Datetime]::UtcNow).AddDays(1)
for ( $i = 1; $i -le $numberofdays; $i++ ) {
# We query one day at a time
$dailyjoblist = Get-AzRecoveryServicesBackupJob -VaultId $backupvault.ID -From $startdate -To $enddate -Operation Backup;
foreach ( $job in $dailyjoblist ) {
#Extract the information for the reports
$message.Body
$newstatsobj = New-Object System.Object
$newstatsobj | Add-Member -type NoteProperty -name Subscription -value (Get-AzSubscription -SubscriptionId $SubscriptionID).Name
$newstatsobj | Add-Member -type NoteProperty -name Date -value $job.StartTime
$newstatsobj | Add-Member -type NoteProperty -name RecoveryVaultName -value $backupvaultname
$newstatsobj | Add-Member -type NoteProperty -name VMName -value $job.WorkloadName
$newstatsobj | Add-Member -type NoteProperty -name Duration -value $job.Duration
$newstatsobj | Add-Member -type NoteProperty -name Status -value $job.Status
$details = Get-AzRecoveryServicesBackupJob -VaultId $backupvault.ID -Job $job
$DAILYBACKUPSTATS += $newstatsobj
}
$enddate = $enddate.AddDays(-1)
$startdate = $startdate.AddDays(-1)
#Sets the columns
$a = "<style>"
$a = $a + "BODY{background-color:white;}"
$a = $a + "TABLE{border-width: 3px;border-style: double;border-collapse: collapse;font-family: Calibri;}"
$a = $a + "TH{border-width: 3px;padding: 2px;border-style: double;background-color:SandyBrown;font-family: Calibri;}"
$a = $a + "TD{border-width: 3px;padding: 2px;border-style: double;font-family: Calibri;}"
$a = $a + "</style>"
}
}
}
$DAILYBACKUPSTATS += $DAILYBACKUPSTATS1
$EmailBody = "<table width='70%'><tbody>"
$EmailBody += "<tr>"
$EmailBody += "<td width='100%' colSpan=4><font face='Calibri' color='#003399' size='3'>Azure Recovery Services Vault Backup Job Status<BR>NOTE: Date is UTC<BR><BR>"
$EmailBody += "</tr>"
$EmailBody += "</table>"
$message1 = $DAILYBACKUPSTATS | ConvertTo-Html -Head $a
$EmailBody += $message1
$content = $emailBody
$VaultName = "Parent-kv"
$SENDGRID_API_KEY = (Get-AzKeyVaultSecret -VaultName $VaultName -Name "Sendgrd-api").SecretValue
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Bearer " + $SENDGRID_API_KEY)
$headers.Add("Content-Type", "application/json")
$destEmailAddress = "jon#mail.com"
$fromEmailAddress = "Azure-NoReply#cla.com"
$body = #{
personalizations = #(
#{
to = #(
#{
email = $destEmailAddress
}
)
}
)
from = #{
email = $fromEmailAddress
}
subject = $subject
content = #(
#{
type = "text/html"
value = $content
}
)
}
$bodyJson = $body | ConvertTo-Json -Depth 4
$response = Invoke-RestMethod -Uri https://api.sendgrid.com/v3/mail/send -Method Post -Headers $headers -Body $bodyJson
You can most likely search here for a whole bunch of potential remedies.
The request was aborted: Could not create SSL/TLS secure channel
I would also recommend to:
verify that the credentials ($SENDGRID_API_KEY) is correct.
run a network sniffer to see the SSL handshake and see if there any exceptions.

Powershell Error: Exception from HRESULT: 0x800A03EC

Any help for this would be great. running into this error and i am unable to figure out why its failing to write to row 4. I have tried different formats and still continues to throw the error. i have tried this in xls and csv. no luck, again any help would be great thank you!
$path = ".\results.csv"
$objExcel = new-object -comobject excel.application
if (Test-Path $path) {
$objWorkbook = $objExcel.WorkBooks.Open($path)
$objWorksheet = $objWorkbook.Worksheets.Item(1)
} else {
$objWorkbook = $objExcel.Workbooks.Add()
$objWorksheet = $objWorkbook.Worksheets.Item(1)
}
$objExcel.Visible = $True
#########Add Header#########
$objWorksheet.Cells.Item(1, 1) = "MachineIP"
$objWorksheet.Cells.Item(1, 2) = "Result"
$objWorksheet.Cells.Item(1, 3) = "HostName"
$objWorksheet.Cells.Item(1, 4) = "ServiceTag"
$ipadd = Read-Host "Please enter the IP address ex. 10.0.0. "
75..190 | ForEach-Object {$ipadd + "$_"} | Out-File -FilePath .\machinelist.txt
Start-Sleep -s 3
$machines = gc .\machinelist.txt
$count = $machines.count
$row=2
$machines | foreach-object{
$ping=$null
$hname =$null
$machine = $_
$ping = Test-Connection $machine -Quiet -Count 1 -ea silentlycontinue
if($ping){
try{
$hname = [System.Net.Dns]::GetHostByAddress($machine).HostName
}catch{}
try{
$stag = Get-WmiObject -ComputerName $machine Win32_BIOS | Select-Object SerialNumber
}catch{}
$objWorksheet.Cells.Item($row,1) = $machine
$objWorksheet.Cells.Item($row,2) = "UP"
$objWorksheet.Cells.Item($row,3) = $hname
$objWorksheet.Cells.Item($row,4) = $stag
$row++
} else {
}
}
Remove-Item -Path .\machinelist.txt -Force
When I ran your code, I saw two issues that kept popping up.
The RPC Server is unavailable (for IP address that didnt resolve)
Unable to assign value to the cell.
For 1, I simply added -ErrorAction SilentlyContinue and for 2, i added quotes around the value for $stag. See script
if($ping){
try{
$hname = [System.Net.Dns]::GetHostByAddress($machine).HostName
}catch{}
try{
$stag = Get-WmiObject -ComputerName $machine Win32_BIOS -ErrorAction SilentlyContinue | Select-Object SerialNumber
$objWorksheet.Cells.Item($row,1) = "$machine"
$objWorksheet.Cells.Item($row,2) = "UP"
$objWorksheet.Cells.Item($row,3) = "$hname"
$objWorksheet.Cells.Item($row,4) = "$stag"
}
catch{
$objWorksheet.Cells.Item($row,1) = "$machine"
$objWorksheet.Cells.Item($row,2) = "DOWN"
$objWorksheet.Cells.Item($row,3) = "$hname"
$objWorksheet.Cells.Item($row,4) = "$stag"
}
$row++
}
If the post helped you get to your solution, please mark the post answered.

Resources