Changing domain of computer using powercli OSCustomizationSpec - powershell

We are trying to automate creation of VMs based on a spread sheet (csv file). These VMs will be based on the template. Template is specified in the sheet. The script works fine and machines are created. However, computer does not join domain. IP and computer name are successfully changed.
Need help in figuring out how to troubleshoot this issue. Following is the snippet used for setting the IP and domain.
New-OSCustomizationSpec -OrgName "Company" -OSType Windows `
-Description $vm.Description -Domain "mydomain" -DomainUsername "domainuser" -DomainPassword "password" `
-ChangeSid -AdminPassword "newpassword" -Name wincli -Type "Persistent" -FullName "Windows Custom Spec"
Get-OSCustomizationNicMapping -OSCustomizationSpec wincli | Set-OSCustomizationNicMapping -Position 1 -IpMode UseStaticIP -IpAddress $vmIP -SubnetMask $vmSubNet -DefaultGateway $vmGateway -Dns $vmDNS1,$vmDNS2 -Confirm:$false
New-OSCustomizationNicMapping –OSCustomizationSpec wincli -Position 2 -IpMode UseStaticIP -IpAddress $vmIP -SubnetMask $vmSubNet -DefaultGateway $vmGateway -Dns $vmDNS1,$vmDNS2 -Confirm:$false
$custom = Get-OSCustomizationSpec -name wincli
$NewVM = New-VM -ResourcePool $resourcePool -Name $vmname -Location $folder -Datastore $datastore -Template $template -OSCustomizationSpec $custom -confirm:$true

Comment from BenH was right on target.
It worked after adding using the format of username as pointed by BenH. (Username: user#domain.xyz.com, domain: domain.xyz.com)

Related

Create Application Gateway probe, backend pool, rules ecc.. with powershell New-AzResources

i'm trying to create with powershell and and command new-AzResources some object, like probe, rules etc.. inside an application gateway. I'm using following snippet:
### Get properties
$get = Get-AzResource -ResourceType Microsoft.Network/applicationGateways -Name appgw -ResourceGroupName rgappgw
$user.Properties.probes.Properties
$properties = #{
protocol = 'Http';
path = '/';
interval = '30';
timeout = '30';
unhealthyThreshold = '3';
pickHostNameFromBackendHttpSettings = $true;
minServers = '0';
match = '200-399';
}
$SlotParams = #{
ResourceName = "appGwName"
Location = "West Europe"
ResourceGroupName = "AppGwRg"
ResourceType = "Microsoft.Network/applicationGateways/probes/probename" ####name of probes
PropertyObject = $properties
}
$execution = New-AzResource #SlotParams -Force
but i'm getting following error:
New-AzResource:
Line |
23 | $getSlotApse = New-AzResource #SlotParams -Force
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| {
"Message": "No HTTP resource was found that matches the request URI 'https://westeurope.network.azure.com:30058/123-124-14-4444-4444444/444444444444/subscriptions/mysubs/resourceGroups/AppGwRg/providers/Microsoft.Network/applicationGateways/appGwName/probes/probename?api-version=2022-07-01'."
}
CorrelationId: 12939812312831983
i use same logic to create app service but i'm not understand what i'm doing wrong with application gateway. Can you please give me an advice?
Thanks
I have reproduced in my environment and taken below commands from the Microsoft-Document:
The command or script which you provided are giving errors for me so, I have used below script for creating application gateway.
Firstly, I have created Subnet then Vnet and all the other required resources using below commands:
Update-Module Az.Network
Connect-AzAccount
$subnet = New-AzVirtualNetworkSubnetConfig -Name subnet01 -AddressPrefix 10.0.0.0/24 -WarningAction Ignore
$vnet = New-AzVirtualNetwork -Name appgwvnet -ResourceGroupName "rithwik-resources" -Location 'East US' -AddressPrefix 10.0.0.0/16 -Subnet $subnet
$subnet = $vnet.Subnets[0]
$publicip = New-AzPublicIpAddress -ResourceGroupName "rithwik-resources" -Name publicIP01 -Location 'East US' -AllocationMethod Dynamic
$gipconfig = New-AzApplicationGatewayIPConfiguration -Name rithwikgatewayIP -Subnet $subnet -WarningAction Ignore
$pool = New-AzApplicationGatewayBackendAddressPool -Name pool01 -BackendIPAddresses 134.170.185.46, 134.170.188.221, 134.170.185.50 -WarningAction Ignore
$probe = New-AzApplicationGatewayProbeConfig -Name probe01 -Protocol Http -HostName 'test.com' -Path '/path/path.htm' -Interval 30 -Timeout 120 -UnhealthyThreshold 8 -WarningAction Ignore
$poolSetting = New-AzApplicationGatewayBackendHttpSettings -Name rithwikapps -Port 80 -Protocol Http -CookieBasedAffinity Disabled -Probe $probe -RequestTimeout 80 -WarningAction Ignore
$fp = New-AzApplicationGatewayFrontendPort -Name frontendport01 -Port 80 -WarningAction Ignore
$fipconfig = New-AzApplicationGatewayFrontendIPConfig -Name fipconfig01 -PublicIPAddress $publicip -WarningAction Ignore
$listener = New-AzApplicationGatewayHttpListener -Name listener01 -Protocol Http -FrontendIPConfiguration $fipconfig -FrontendPort $fp -WarningAction Ignore
$rule = New-AzApplicationGatewayRequestRoutingRule -Name rule01 -RuleType Basic -BackendHttpSettings $poolSetting -HttpListener $listener -BackendAddressPool $pool -WarningAction Ignore
$sku = New-AzApplicationGatewaySku -Name Standard_Small -Tier Standard -Capacity 2 -WarningAction Ignore
$appgw = New-AzApplicationGateway -Name appgwtest -ResourceGroupName "rithwik-resources" -Location 'East US' -BackendAddressPools $pool -Probes $probe -BackendHttpSettingsCollection $poolSetting -FrontendIpConfigurations $fipconfig -GatewayIpConfigurations $gipconfig -FrontendPorts $fp -HttpListeners $listener -RequestRoutingRules $rule -Sku $sku -WarningAction Ignore
Output:
Once ran the above commands in powershell then the resources are created in Portal

HDInsight cluster with metastore using powershell error

I am trying to create HDInsight cluster in Azure with Metastore using the Powershell script. But it is throwing BadRequest: RegionCapabilityNotAvailable,Region capability not available for region 'East US' error. But East US is a supported region for the HDInsight cluster. Please find my code below.
$storageAccountResourceGroupName = "hdi-rg"
$storageAccountName = "qwertyhdi"
#$storageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $storageAccountResourceGroupName -Name $storageAccountName)[0].value
$storageContainer = "qwertyiopasdf-2020-05-03t08-30-23-118z"
# Cluster configuration info
$location = "East US"
$clusterResourceGroupName = "hdi-rg"
$clusterName = "qwertyiopasdf"
$username = "admin"
$password = ConvertTo-SecureString "password" -AsPlainText -Force
$clusterCreds = New-Object System.Management.Automation.PSCredential -ArgumentList ($username, $password)
# Hive metastore info
$hiveSqlServer = "server"
$hiveDb = "db123"
$sqlusername = "qwerty"
$sqlpassword = ConvertTo-SecureString "password" -AsPlainText -Force
$hiveCreds = New-Object System.Management.Automation.PSCredential -ArgumentList ($sqlusername, $sqlpassword)
New-AzStorageAccount `
-ResourceGroupName $storageAccountResourceGroupName `
-Name $storageAccountName `
-Location $location `
-SkuName Standard_LRS `
-Kind StorageV2 `
-EnableHttpsTrafficOnly 1
# Note: Storage account kind BlobStorage cannot be used as primary storage.
$storageAccountKey = (Get-AzStorageAccountKey `
-ResourceGroupName $storageAccountResourceGroupName `
-Name $storageAccountName)[0].Value
$defaultStorageContext = New-AzStorageContext `
-StorageAccountName $storageAccountName `
-StorageAccountKey $storageAccountKey
New-AzStorageContainer `
-Name $storageContainer `
-Context $defaultStorageContext #use the cluster name as the container name
$metastore = New-AzHDInsightClusterConfig | Add-AzHDInsightMetastore -SqlAzureServerName "$hiveSqlServer.database.windows.net" -DatabaseName $hiveDb -Credential $hiveCreds -MetastoreType HiveMetastore
New-AzHDInsightCluster -Location $location -ResourceGroupName $clusterResourceGroupName -ClusterName $clusterName -ClusterType Hadoop -OSType Windows -ClusterSizeInNodes 1 -HttpCredential $clusterCreds -DefaultStorageAccountName "$storageAccountName.blob.core.windows.net" -DefaultStorageAccountKey $storageAccountKey -DefaultStorageContainer $storageContainer -Config $metastore
Is -OSType Windows still valid. I realize "Windows" is listed as an option from the PowerShell specs, but I think "linux" is the only value that will actually work.
You will receive this error message BadRequest: RegionCapabilityNotAvailable,Region capability not available for region 'East US', when underlying compute sku is not available for the selected region in that subscription.
I would request you to check if the resource are available from Azure Portal.
Azure Portal => Select your subscription => Usage + Quotas
Filter with => Microsoft.Compute and Region => East US
If you're unable to find a suitable SKU in that region/zone or an alternative region/zone that meets your business needs, submit a SKU request or Quota increase to Azure Support.

Add a Azure WebApp to an Existing VPN using a Point-to-Site connection (RM Powershell)

I have hunted around for an answer to this, but I am not having much luck. All the articles I can find are either setting up a Point-to-Site or are instructions for classic Azure, not Azure 2.0 (Resource Group)
Currently, we are dialing up a whole new resource group everytime we do a new built. This consists of Web apps and SQL DBs. When we have a new build we start up the new and del the old resource group. Simple. To minimize the start-up time we have a static resource group that isn't deleted that houses the VPN connection to our on Prem resources.
The problem I'm having is when I add the new websites using AzureRM Powershell cmd's to the Point-to-site it says it's successful. The Azure Portal says its good but it does let me communicate. If I remove and add it from one of the 8 WebApps they all start working.
I am out of ideas. Any help would be greatly appreciated.
Azure VPN
Below is the function I have put togeather from what I can find out there.
function AddExistingVnet{
param(
[string] $subscriptionId,
[string] $resourceGroupName,
[string] $webAppName
)
$Vnet = Get-AzureRmVirtualNetwork | Where-Object {$_.ResourceGroupName -like "*Static*"}
IF($Vnet.Name.count -gt 1) {write-host 'Two or networks have been returned. Unable to continue ' return}
$gatewaySubnet = $vnet.Subnets | Where-Object { $_.Name -eq "GatewaySubnet" }
$vnetName = $vnet.Name
$uriParts = $gatewaySubnet.IpConfigurations[0].Id.Split('/')
$gatewayResourceGroup = $uriParts[4]
$gatewayName = $uriParts[8]
$gateway = Get-AzureRmVirtualNetworkGateway -ResourceGroupName $vnet.ResourceGroupName -Name $gatewayName
Write-Host "Creating App association to VNET"
$propertiesObject = #{
"vnetResourceId" = "/subscriptions/$($subscriptionId)/resourceGroups/$($vnet.ResourceGroupName)/providers/Microsoft.Network/virtualNetworks/$($vnetName)"
}
$virtualNetwork = New-AzureRmResource -Location $location -Properties $PropertiesObject -ResourceName "$($webAppName)/$($vnet.Name)" -ResourceType "Microsoft.Web/sites/virtualNetworkConnections" -ApiVersion 2015-08-01 -ResourceGroupName $resourceGroupName -Force
# Now finish joining by getting the VPN package and giving it to the App
Write-Host "Retrieving VPN Package and supplying to App"
$packageUri = Get-AzureRmVpnClientPackage -ResourceGroupName $vnet.ResourceGroupName -VirtualNetworkGatewayName $gateway.Name -ProcessorArchitecture Amd64
# Put the VPN client configuration package onto the App
$PropertiesObject = #{
"vnetName" = $vnet.Name; "vpnPackageUri" = $packageUri
}
New-AzureRmResource -Location $location -Properties $PropertiesObject -ResourceName "$($webAppName)/$($vnet.Name)/primary" -ResourceType "Microsoft.Web/sites/virtualNetworkConnections/gateways" -ApiVersion 2015-08-01 -ResourceGroupName $resourceGroupName -WarningAction silentlyContinue -Force
}
So after 2 weeks of going back and forth with Microsoft (had a really good guy Charles) we managed to find the problem.
When requesting
$packageUri = Get-AzureRmVpnClientPackage -ResourceGroupName $vnet.ResourceGroupName -VirtualNetworkGatewayName $gateway.Name -ProcessorArchitecture Amd64
It was giving me an output of:
"https://mdsbrketwprodsn1prod.blob.core.windows.net/cmakexe/xxx~xxx/amd64/xxxx~xxxx&sp=r&fileExtension=.exe"
For some reason (that Microsoft could explain) why it kept adding in " to the beginning and end of the variable.
I find it odd that it lets the script work with " and allows the WebApps to join to the VPN.
Any why here is the fix which basicly removes the " from the begining and end of $packageUri :
$packageUri = $packageUri.ToString();
$packageUri = $packageUri.Substring(1, $packageUri.Length-2);
So hope that helps someone else out there who is banging there head agaist the same problem.
Here is the complete function if any one is intrested:
function AddExistingVnet{
param(
[string] $subscriptionId,
[string] $resourceGroupName,
[string] $webAppName
)
$Vnet = Get-AzureRmVirtualNetwork | Where-Object {$_.ResourceGroupName -like "*Static*"}
IF($Vnet.Name.count -gt 1) {write-host 'Two or networks have been returned. Unable to continue ' return}
$gatewaySubnet = $vnet.Subnets | Where-Object { $_.Name -eq "GatewaySubnet" }
$vnetName = $vnet.Name
$uriParts = $gatewaySubnet.IpConfigurations[0].Id.Split('/')
$gatewayResourceGroup = $uriParts[4]
$gatewayName = $uriParts[8]
$gateway = Get-AzureRmVirtualNetworkGateway -ResourceGroupName $vnet.ResourceGroupName -Name $gatewayName
$webApp = Get-AzureRmResource -ResourceName $webAppName -ResourceType "Microsoft.Web/sites" -ApiVersion 2015-08-01 -ResourceGroupName $resourceGroupName
$location = $webApp.Location
Write-Host "Creating App association to VNET"
$propertiesObject = #{
"vnetResourceId" = "/subscriptions/$($subscriptionId)/resourceGroups/$($vnet.ResourceGroupName)/providers/Microsoft.Network/virtualNetworks/$($vnetName)"
}
$virtualNetwork = New-AzureRmResource -Location $location -Properties $PropertiesObject -ResourceName "$($webAppName)/$($vnet.Name)" -ResourceType "Microsoft.Web/sites/virtualNetworkConnections" -ApiVersion 2015-08-01 -ResourceGroupName $resourceGroupName -Force
# Now finish joining by getting the VPN package and giving it to the App
Write-Host "Retrieving VPN Package and supplying to App"
$packageUri = Get-AzureRmVpnClientPackage -ResourceGroupName $vnet.ResourceGroupName -VirtualNetworkGatewayName $gateway.Name -ProcessorArchitecture Amd64
$packageUri = $packageUri.ToString();
$packageUri = $packageUri.Substring(1, $packageUri.Length-2);
# Put the VPN client configuration package onto the App
$PropertiesObject = #{
"vnetName" = $vnet.Name; "vpnPackageUri" = $packageUri.ToString()
}
$date = Get-Date -format "HH:mm tt"
New-AzureRmResource -Location $location -Properties $PropertiesObject -ResourceName "$($webAppName)/$($vnet.Name)/primary" -ResourceType "Microsoft.Web/sites/virtualNetworkConnections/gateways" -ApiVersion 2015-08-01 -ResourceGroupName $resourceGroupName -WarningAction silentlyContinue -Force
}
Enjoy

Azure: How to check storage account exists in Azure with Get-AzureStorageAccount

I am building a power shell script to automate the setup of a website environment in Azure. This web uses an account storage. I want to the script not to create the account storage if exists.
I thought that using Get-AzureStorageAccount this way may work but it does not:
Write-Verbose "[Start] creating $Name storage account $Location location"
$storageAcct = Get-AzureStorageAccount –StorageAccountName $Name
if (!$storageAcct)
{
$storageAcct = New-AzureStorageAccount -StorageAccountName $Name -Location $Location -Verbose
if ($storageAcct)
{
Write-Verbose "[Finish] creating $Name storage account in $Location location"
}
else
{
throw "Failed to create a Windows Azure storage account. Failure in New-AzureStorage.ps1"
}
}
else
{
Write-Verbose "$Name storage account in $Location location already exists, skipping creation"
}
The issue is I don't know how to handle the return of Get-AzureStorageAccount.
Thank you very much in advance!
I would suggest using the Test-AzureName cmdlet to determine if it exists. So, something like this.
if (!(Test-AzureName -Storage $Name))
{
Write-Host "Creating Storage Account $Name"
New-AzureStorageAccount -StorageAccountName $Name -Location $Location
}
You can use Test-AzureName for other services too, such as Cloud Services, WebSites, and ServiceBus. It returns True if it exists, False otherwise.
Get-AzureRmStorageAccountNameAvailability -Name "accountname"
Try this:
$Name = "myStorageAccount"
$Location = "myLocation"
Write-Host "[Start] creating $Name storage account $Location location"
try{
Get-AzureStorageAccount –StorageAccountName $Name -ErrorAction Stop | Out-Null
Write-Host "$Name storage account in $Location location already exists, skipping creation"
}
catch{
Write-Host "[Finish] creating $Name storage account in $Location location"
New-AzureStorageAccount -StorageAccountName $Name -Location $Location -Verbose
}
Test-AzureName didn't work with our build agents and we already had a try/catch in code so a second one would require building it out as a function. I opted for that standard get and check if null, use -ErrorAction Ignore to stop it throwing an exception
# Check for storage account and create if not found
$StorageAccount = Get-AzureRmStorageAccount -Name $StorageAccountName -ResourceGroupName $StorageAccountRG -ErrorAction Ignore
if ($StorageAccount -eq $null)
{
New-AzureRmStorageAccount -Location "West Europe" -Name $StorageAccountName -ResourceGroupName $StorageAccountRG -SkuName Standard_LRS -Kind Storage
$StorageAccount = Get-AzureRmStorageAccount -Name $StorageAccountName -ResourceGroupName $StorageAccountRG
}
#Rick Rainey's solution works if you're logged in using Add-AzureAccount. However, Azure and powershell have a conflicting and confusing suite of login accounts (Windows Live versus AD) and login mechanisms (Classic: Add-AzureAccount; Resource manager: Login-AzureRmAccount). Some Azure powershell cmdlets require a specific login; further, some require a specific account type!
To clear through this thicket of complicated, undocumented, and confusing permission issues, we always use an AD account, logging in via Login-AzureRmAccount. We also use Azure resource manager (ARM) resources and cmdlets, following Microsoft's movement to ARM as its recommended and strategic approach. However, #RIck's solution is one which the ARM login doesn't work with. :-( So you need another approach, which is #Darren's (for storage). However, for a generic replacement for Test-AzureName I'd suggest Find-AzureRmResource. In the case of storage
$StorageObject = Find-AzureRmResource -ResourceType "Microsoft.Storage/storageAccounts" | Where-Object {$_.Name -eq $storageName}
if ( !$StorageObject ) {
$storageLocation = (Get-AzureRmResourceGroup -ResourceGroupName $resourceGroup).Location
$storageType = "Standard_LRS"
New-AzureRmStorageAccount -ResourceGroupName $resourceGroup -Name $storageName -Location $storageLocation -Type $storageType
}
You should use the latest Powershell module Az.
if ($(Get-AzStorageAccount -ResourceGroupName $resourceGroupName -Name $storageAccountName) -eq $null)
{
# does not exist
}
With the current Az module for PowerShell Version 7, the Get-AzStorageAccountNameAvailability cmdlet might offer a more efficient solution as it was designed specifically for this task. Here is an example:
# ... declare variables and specify values ...
$checkNameAvail = (Get-AzStorageAccountNameAvailability -Name $storageAccountName) | `
Select-Object NameAvailable
if ($checkNameAvail.NameAvailable)
{
Write-Host 'Account name available! Please wait while your resource is being created'
# Create account. Variables used in this example would have been declared earlier in the script.
$storageAccount = (New-AzStorageAccount -ResourceGroupName $resourceGroupName `
-AccountName $storageAccountName `
-Location $location `
-SkuName $skuType `
-AllowBlobPublicAccess $false -EnableHttpsTrafficOnly $true)
# ...
}
else
{
# This section of the script executes if the name is not available
Write-Host "The name <$storageAccountName> is not available. Suggest a new globally unique name!"
}
The condition above will return False, and execute the else statement because the boolean value returned by the cmdlet is in [0] as shown in the PowerShell command-line test below. The availability information (boolean) can thus be stripped from the object returned by the cmdlet and (as in this example) used as a condition in the rest of the script.
PS C:\> Get-AzStorageAccountNameAvailability -Name testaccount1
NameAvailable Reason Message
------------- ------ -------
False AlreadyExists The storage account named testaccount1 is already taken.
Use the error variable
Get-AzStorageAccount -ResourceGroupName 'RG-QA-TEST' -Name 'staccountfor12334ff' -ErrorVariable ev1 -ErrorAction SilentlyContinue
if ($ev1) {
Write-Host "-------------------------- Creating OEM Storage"
//create storage account
}
I had this challenge when setting up Azure storage accounts for Static website hosting using Powershell in Octopus Deploy.
Here's how I fixed it:
Using the Az module for Azure Powershell I did the following:
# Define Variables
$RESOURCE_GROUP_NAME = my-resource-group
$LOCATION = northeurope
$STORAGE_ACCOUNT_NAME = myapplication
$SKU_NAME = Standard_GRS
$STORAGE_KIND = StorageV2
# Check Storage Account and Create if not Found
$STORAGE_ACCOUNT = Get-AzStorageAccount -ResourceGroupName $RESOURCE_GROUP_NAME -Name $STORAGE_ACCOUNT_NAME -ErrorAction Ignore
if ($STORAGE_ACCOUNT -eq $null) {
Write-Host 'Creating storage account'
New-AzStorageAccount -ResourceGroupName $RESOURCE_GROUP_NAME -AccountName $STORAGE_ACCOUNT_NAME -Location $LOCATION -SkuName $SKU_NAME -Kind $STORAGE_KIND
Write-Host "$STORAGE_ACCOUNT_NAME storage account successfully created"
}
else {
Write-Host "$STORAGE_ACCOUNT_NAME storage account already exists"
}
Note:
-ErrorAction Ignore - This ignores the exception that would arise if the storage account does not exist
Write-Host " " - Double quotes were used to allow for string interpolation since we are connecting strings and variables.
That's all.
I hope this helps

Booting from an ISO image using PowerCLI scripts

How do I make the following script work? Currently I am able to create a new virtual machine in my server. I wish to also load the Windows ISO image and do an unattended installation in the virtual machine. How shall I edit the script to make this work?
# Virtual Center Details
$server_address = "xxxxx"
$username = "xxxxx"
$password = "xxxxx"
$iso = "WINXP_X86_SP3_CD.ISO"
Get-VIServer -Server $server_address -Protocol https -User $username -Password $password
foreach ($vmm in $array)
{
$vmm = "VirtualMachine"
New-VM -name $vmm -DiskMB 20000 -memoryMB 2000
Get-VM $vmm | Get-CDDrive | Set-CDDrive -IsoPath $iso -StartConnected $true -Confirm:$false
$value = "5000"
$vm = Get-VM $vmname | Get-View
$vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
$vmConfigSpec.BootOptions = New-Object VMware.Vim.VirtualMachineBootOptions
$vmConfigSpec.BootOptions.BootDelay = $value
$vm.ReconfigVM_Task($vmConfigSpec)
Start-vm -vm $vmname
}
my issue is with the ISO PATH image. I am getting the error "Invalid datastore format"
You are specifying isopath using IsoPath parameter, which is the datastore path to the ISO, not simply the ISO name. From your code you are not indicating any datastore.
The syntax for a datastore path is:
"[yourdatastore] IsoFolder\$iso"
Example got from PowerCLI reference online:
$cd = New-CDDrive -VM $vm -ISOPath "[sof-20666-esx:storage1] ISO\testISO.iso"
Set-CDDrive -CD $cd -StartConnected -Connected