I have a script which spins up an Azure VM and specifies an admin username and password.
Is it possible to have the script setup a second admin? The reason for this is so that more than one user can be on the machine at the same time.
Do you have access to the vm with Invoke-Command?
If yes, might this helps: How to Manage Local Users and Groups using PowerShell
According to my research, two users can access Azure windows VM concurrently. A maximum of two concurrent connections are supported unless the server is configured as a Remote Desktop Services session host. Regarding how to add local user to Azure VM, you use the the VM Access extension in Azure PowerShell. For more details, please refer to the document
For example
Connect-AzAccount
$vm = Get-AzVM -ResourceGroupName jimtest -Name jimtest
$name = "jimtest1"
$password = "Pass***!"
$secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
$mycred= New-Object System.Management.Automation.PSCredential ($name, $secpasswd)
Set-AzVMAccessExtension -Credential $mycred -ResourceGroupName $vm.ResourceGroupName -VMName $vm.Name -Location $vm.Location -Name VMAccessAgent -TypeHandlerVersion "2.0"
You can use this PowerShell command below to add an admin account to your VM :
$adminName = "testadmin"
$passstr = "password123!"
$Password = ConvertTo-SecureString -String $passstr -AsPlainText -Force
New-LocalUser $adminName -Password $Password -FullName $adminName -Description "test admin account"
Add-LocalGroupMember -Group "Administrators" -Member $adminName
And you can use the Powershell command below to run your custom Powershell command on your Azure VMs(get started with azure powershell see here):
Connect-AzAccount
$vm = Get-AzVM -Name "<your vm name>" -ResourceGroupName "<your vm resource group>"
Invoke-AzVMRunCommand -VM $vm -CommandId 'RunPowerShellScript' -ScriptPath "<path of adding admin account command>"
so just save the first part command as a .ps1 file , and copy the path as value of you can add an local admin account to your VM.
Result :
Related
I have a subscription I want to pause/resume with a PowerShell script (Azure Analysis Services). I use this exact same script to pause my Embedded Capacity and that works fine, but when I run my script for my new subscription it wont work. This is the script I use:
$userPassword = "myappsecret"
$userPassword2 = ConvertTo-SecureString -String $userPassword -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "appid", $userPassword2
Connect-AzAccount -ServicePrincipal -TenantId "tenantid" -Credential $Credential
Select-AzSubscription -SubscriptionId "subscriptionname here"
Get-AzPowerBIEmbeddedCapacity -ResourceGroupName "groupnamehere" -Name "namehere"
Suspend-AzPowerBIEmbeddedCapacity -Name "namehere" -ResourceGroupName "groupnamehere" -PassThru
To check why this won't work I tried to simply use Get-AzSubscription to see if something was wrong and it wont show any subscription.
If I try the same for my Embedded Capacity it works just fine.
What could be wrong?
To get the list of all Azure Ad subscriptions by using Get-AzSubscription, make sure that you have owner/admin role.
You can make use of the below command to get Azure Ad subscriptions for a specific tenant:
Make sure to connect-azaccount with Administrator details.
Get-AzSubscription -TenantId "your_tenant_id"
Get-AzContext command list the information of the Azure Subscription that is currently selected.
To use a specific subscription, you can make use of below command:
Get-AzSubscription -SubscriptionId "xxxx-xxxx-xxxx-xxxx" -TenantId "yyyy-yyyy-yyyy-yyyy" | Set-AzContext
Or please modify your code by adding the below snippet:
$subscriptionId = 'Your_Subscription_ID';
Select-AzSubscription -SubscriptionId $subscriptionId
You can check the Subscription Id via Azure Portal too.
Reference:
Get-AzSubscription (Az.Accounts) | Microsoft Docs
After create a runbook and edit content, I want to create variable and set value for them. How can I do it by ansible or azure cli ?
Please help me
Azure Automation stores each encrypted variable securely. When you create a variable, you can specify its encryption and storage by Azure Automation as a secure asset.
You must set the value with the Set-AzAutomationVariable cmdlet or the internal Set-AutomationVariable cmdlet. You use the Set-AutomationVariable in your runbooks that are intended to run in the Azure sandbox environment, or on a Windows Hybrid Runbook Worker.
You can create variables and set value for them using PowerShell script.
$rgName = "ResourceGroup01"
$accountName = "MyAutomationAccount"
$vm = Get-AzVM -ResourceGroupName "ResourceGroup01" -Name "VM01" | Select Name, Location,Extensions
New-AzAutomationVariable -ResourceGroupName "ResourceGroup01" -AutomationAccountName "MyAutomationAccount" -Name "MyComplexVariable" -Encrypted $false -Value $vm
$vmValue = Get-AzAutomationVariable -ResourceGroupName "ResourceGroup01" -AutomationAccountName "MyAutomationAccount" -Name "MyComplexVariable"
$vmName = $vmValue.Value.Name
$vmTags = $vmValue.Value.Tags
Reference: Manage variables in Azure Automation | Microsoft Docs
I need help on this scenario. we have a cert in azure key vault which needs to be download to a windows VM for our .net application to run on iis. I am able to upload the cert to Azure keyvault with out issues. I am running a azure devops powershell tasks inline powershell script.
it will connect to azure using conenct-azaccount with appropriate login creds.enter code here
we run invoke-azvmssruncommand and specific the script path and variable which needs to be passed as parameters.
in the PowerShell script we have script to get the cert from azure keyvualt once its connected to azure vm
below is the error
error: an error occurred while sending request. need your thoughts on it.
Invoke-AzVmssVMRunCommand -VMScaleSetName dev-CTUS -ResourceGroupName RG -InstanceId $instanceid -CommandId 'RunPowerShellScript'-ScriptPath "path"\downloadcertfromkeyvault.ps1" -Parameter #{"vaultname"= "keyvault name";"certname"="app-DEV";"password"= "jdksjkdjalksd";"said"="";"sapuserid"; password"="password";"devSubscriptionId"="ZXXXXXXXXXX"} -Debug
this is the command which i used in azure devops powershell inline script .
inside powershell script
$SecurePassword = "$sapassword" | ConvertTo-SecureString -AsPlainText -Force
$Credential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $said, $SecurePassword
Connect-AzAccount -Credential $Credential -Tenant "XXXXXXXXXXXX-a68c-41e5-XXXXXXXX"
Write-log "setting subscription to retrive certs"
Set-AzContext $devSubscriptionId
$password = "$password"
$password = ConvertTo-SecureString -String "$password" -AsPlainText -Force
$cert = Get-AzKeyVaultCertificate -VaultName $vaultname -Name $certname
$secret = Get-AzKeyVaultSecret -VaultName $vaultname -Name $cert.Name
$pfxpath = [System.Environment]::GetFolderPath("Desktop")
$secretByte = [Convert]::FromBase64String($secret.SecretValueText)
$x509Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($secretByte, "", "Exportable,PersistKeySet")
$type = [System.Security.Cryptography.X509Certificates.X509ContentType]::Pfx
$pfxFileByte = $x509Cert.Export($type, $password)
# Write to a file
[System.IO.File]::WriteAllBytes("$pfxpath\$certname.pfx", $pfxFileByte)
$certificate= Get-ChildItem -path cert:\LocalMachine\My` `
Write-Log $certificate
I have setup a Shared Image Gallery and added a VM image to it. I can provision a new VM in my subscription from it. A friend wants to use that same image to provision the same VM in his subscription, a totally different Azure account. He has added me temporarily as an owner to his subscription and I can change directory from my azure portal to access and work with it no problem.
When I try to create a VM, I can't find the gallery in my subscription/account from his subscription (a totally different Azure account).
I have tried making an application registration and even added permissions for the application in his subscription too (contributor). Still can't see it.
Is this possible at all or am I doing something wrong?
thank you much
At the moment, we have no way to use the portal to deploy a VM from an image in another azure tenant. To create a VM from an image shared between tenants, you must use the Azure CLI or Powershell. For more details, please refer to here
For example
create a service principal in the tenant 1
Give Tenant 2 access
a. Register the sp into tenant 2
we can implement it by requesting a sign-in using a browser
https://login.microsoftonline.com/<Tenant 2 ID>/oauth2/authorize?client_id=<Application (client) ID>&response_type=code&redirect_uri=https%3A%2F%2Fwww.microsoft.com%2F
b. Assign Azure RABC role Contributor to the sp
Create VM
a. Log into both tenants using the application ID, secret and tenant ID.
$applicationId = '<App ID>'
$secret = <Secret> | ConvertTo-SecureString -AsPlainText -Force
$tenant1 = "<Tenant 1 ID>"
$tenant2 = "<Tenant 2 ID>"
$cred = New-Object -TypeName PSCredential -ArgumentList $applicationId, $secret
Clear-AzContext
Connect-AzAccount -ServicePrincipal -Credential $cred -Tenant $tenant1
Connect-AzAccount -ServicePrincipal -Credential $cred -Tenant $tenant2
b. Create VM
$resourceGroup = ""
$location = ""
$vmName = ""
# Set a variable for the image version in Tenant 1 using the full image ID of the shared image version
$image = "/subscriptions/<Tenant 1 subscription>/resourceGroups/<Resource group>/providers/Microsoft.Compute/galleries/<Gallery>/images/<Image definition>/versions/<version>"
# Create user object
$cred = Get-Credential -Message "Enter a username and password for the virtual machine."
# Create a resource group
New-AzResourceGroup -Name $resourceGroup -Location $location
# Networking pieces
$subnetConfig = New-AzVirtualNetworkSubnetConfig -Name mySubnet -AddressPrefix 192.168.1.0/24
$vnet = New-AzVirtualNetwork -ResourceGroupName $resourceGroup -Location $location `
-Name MYvNET -AddressPrefix 192.168.0.0/16 -Subnet $subnetConfig
$pip = New-AzPublicIpAddress -ResourceGroupName $resourceGroup -Location $location `
-Name "mypublicdns$(Get-Random)" -AllocationMethod Static -IdleTimeoutInMinutes 4
$nsgRuleRDP = New-AzNetworkSecurityRuleConfig -Name myNetworkSecurityGroupRuleRDP -Protocol Tcp `
-Direction Inbound -Priority 1000 -SourceAddressPrefix * -SourcePortRange * -DestinationAddressPrefix * `
-DestinationPortRange 3389 -Access Allow
$nsg = New-AzNetworkSecurityGroup -ResourceGroupName $resourceGroup -Location $location `
-Name myNetworkSecurityGroup -SecurityRules $nsgRuleRDP
$nic = New-AzNetworkInterface -Name myNic -ResourceGroupName $resourceGroup -Location $location `
-SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -NetworkSecurityGroupId $nsg.Id
# Create a virtual machine configuration using the $image variable to specify the shared image
$vmConfig = New-AzVMConfig -VMName $vmName -VMSize Standard_D1_v2 | `
Set-AzVMOperatingSystem -Windows -ComputerName $vmName -Credential $cred | `
Set-AzVMSourceImage -Id $image | `
Add-AzVMNetworkInterface -Id $nic.Id
# Create a virtual machine
New-AzVM -ResourceGroupName $resourceGroup -Location $location -VM $vmConfig
I'm new to Azure. I'm trying to create resources in Azure using powershell.
My requirement is to create an image from a VM. I have followed to ways to do it :
Process 1: Do it manually
Generalize the VM : Login to VM -> Open command prompt -> cd %windir%\system32\sysprep --> run sysprep.exe --> Check generalize button--> Shutdown.
Create snapshot : Go to Azure portal-> Go to the VM which is generalized --> Click on Capture button --> Give image name and mention resource group and click on Create.
This will create an Image.
Process 2: Do it with powershell
# create session of the VM
$UserName = "$IPAddress\$adminUsername"
$Password = ConvertTo-SecureString $adminPassword -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($UserName, $Password)
$s = New-PSSession -ComputerName $IPAddress -Credential $psCred
# Run SysPrep for generalizing the VM
$sysprep = 'C:\Windows\System32\Sysprep\Sysprep.exe'
$arg = '/generalize /oobe /shutdown /quiet'
Invoke-Command -Session $s -ScriptBlock {param($sysprep,$arg)Start-Process -FilePath $sysprep -ArgumentList $arg} -ArgumentList $sysprep,$arg
#Stop the VM
Stop-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $virtualMachineName -Force
# Generalize the VM
Set-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $virtualMachineName -Generalized
# Create the Image
$vm = Get-AzureRmVM -Name $virtualMachineName -ResourceGroupName $ResourceGroupName
$image = New-AzureRmImageConfig -Location $location -SourceVirtualMachineId $vm.ID
New-AzureRmImage -Image $image -ImageName $ImageName -ResourceGroupName $ResourceGroupName
Both the processes will create a Image. But the problem I'm facing here is when I spin VM from the image created from Process 1 , it is created successfully without any issue.
But when I spin VM from image created from Process2 , it is getting created but with below error message :
Provisioning failed. OS Provisioning for VM 'VM Name' did not finish
in the allotted time. However, the VM guest agent was detected
running. This suggests the guest OS has not been properly prepared to
be used as a VM image (with CreateOption=FromImage).
Can anyone tell me what it is I'm doing wrong with powershell script, that I'm getting this error.
Time seems to be the issue.
Sysprep normally takes 10 - 15 minutes, you have no sleep time. You are shutting down VM as soon as the sysprep script is sent, no time to actually sysprep system.
You can either put a sleep time or a loop to check when VM is in a Stopped state.
There are quite a few docs on papering and creating VMs from images in Azure. As the error suggests, you likely missed a step.
If you are uploading a VHD from on prem to use in Azure, start with these docs
https://learn.microsoft.com/en-us/azure/virtual-machines/windows/prepare-for-upload-vhd-image
https://learn.microsoft.com/en-us/azure/virtual-machines/windows/upload-generalized-managed
If the VM you are capturing an image of is already in Azure and working, then start with these
https://learn.microsoft.com/en-us/azure/virtual-machines/windows/capture-image-resource
https://learn.microsoft.com/en-us/azure/virtual-machines/windows/create-vm-generalized-managed?toc=%2fazure%2fvirtual-machines%2fwindows%2ftoc.json
The last link shows you how to create the VM from that image via the portal or a simple PS command
New-AzVm `
-ResourceGroupName "myResourceGroup" `
-Name "myVMfromImage" `
-ImageName "myImage" `
-Location "East US" `
-VirtualNetworkName "myImageVnet" `
-SubnetName "myImageSubnet" `
-SecurityGroupName "myImageNSG" `
-PublicIpAddressName "myImagePIP" `
-OpenPorts 3389