New-VM - "The operation is not supported on this object" - powershell

I am trying to clone a VM using PowerCLI. Running the following snippet returns the error "The operation is not supported on the object."
$vmHost = Get-VMHost
New-VM -Name VM1 -VM SourceVM -VMHost $vmHost
Why does this return: 'operation not supported on the object error'
There is only one host, so it's not an issue with $vmHost selection.
Thanks

I'm recreating this error with PowerCLI 6.5R1 directly connected to the ESXi host rather than to the vCenter server (with Connect-VIServer). The New-VM line you have works fine when connected to vCenter. So I'd suggest doing that if you're able. Otherwise it might be something to take up with VMware. If you don't have a support contract, you could try their Forums.
edit - You can't clone a vm without vCenter (thanks #Jelphy) although in a pinch you could copy the disks.

Related

PowerCLI - Get VM Disk Partition Type

I'm looking to conduct an audit on our virtual environment to get the disk partition types (MBR, GPT) of our VMs. I haven't found any documentation in PowerCLI to get the partition type. Any ideas how I can go about this? Thanks!
That sort of information is normally not known at the VM object level and instead known at the Guest-OS level. If the VMs you're working with have VMware Tools (or Open VM Tools), you can still use PowerCLI to run scripts against them to pull that information with Invoke-VMScript (docs), but you'll still need to write your own code to pass to the guest OS to pull partition type.
If they're windows systems, you may be able to do something as simple as:
Invoke-VMScript -ScriptText {Get-Partition | select DriveLetter, Type} -VM VMName -GuestCredential $guestCredential
Thanks #Kyle Ruddy!
This was what I did:
$vmName = "VM NAME"
$output = Invoke-VMScript -ScriptText {Get-Disk | select Number, #{name='Size (GB)';expr={[int]($_.Size/1GB)}}, PartitionStyle} -VM $vmName -GuestUser $Username -GuestPassword $Password
$output.ScriptOutput | FT -AutoSize

How to Get MAC Address of VMs with Azure PowerShell

Does anyone know how to get Mac address of vms in Azure through Azure PowerShell?
i know i can get it with WMI or something else inside the VM, but i don't know how can i do that without logging on the VM.
Use the Get-AzureRmNetworkInterface command and the MacAddress property the resulting object has:
(Get-AzureRmNetworkInterface -ResourceGroupName %rgName%).MacAddress
this will list all the macs of the network interfaces in a resource group, to be more specific you could add the -Name parameter.
(Get-AzureRmNetworkInterface -ResourceGroupName %rgName% -Name %nicName%).MacAddress

Get status of service on a remote server

I need to find the status of a service on a remote computer. Though I can use the following command:
Write-Host (Get-Service -ComputerName "remoteServerName" -Name "serviceName").Status
which would give me correct status of service. However I have PowerShell 1.0 installed on the server where i need to run this script. -ComputerName parameter doesn't work for PowerShell 1.0. Currently I'm not supposed to install higher version of PowerShell.
Any idea how to get the status of a service in PowerShell 1.0?
First and foremost (and I can't stress this point enough): If the operating system supports it you should upgrade to at least PowerShell v2.0. No exception. If the system doesn't support PowerShell 2 or newer it's already out of support and should have been replaced/upgraded months ago.
With that said, you can use either WMI (as suggested by #vonPryz):
Get-WmiObject -Computer 'remoteServerName' -Class Win32_Service -Filter "DisplayName='ServiceName'"
or sc.exe (as suggested by #Kayasax):
& sc.exe \\remoteServerName query 'ServiceName'
Of these two WMI is the more PoSh approach, as it doesn't require parsing text output.

Remove-AzureDisk throws error, not sure why

I have an Azure VM and I'm trying to delete it using Powershell. I also want to remove the disk that that VM OS was on (there are no data disks).
I assume I'm going to need the following two cmdlets:
Remove-AzureVM
Remove-AzureDisk
Here's my code:
$VMs = Get-AzureVM $svcName
foreach ($VM in $VMs)
{
$OSDisk = ($VM | Get-AzureOSDisk)
if ($VM.InstanceStatus -eq "ReadyRole") {
Stop-AzureVM -Name $VM.Name -ServiceName $svcName
}
remove-azurevm -ServiceName $svcName -Name $VM.Name
Remove-AzureDisk -DiskName $OSDisk.DiskName
}
When I execute this the call to Remove-AzureVM returns successfully but the call to Remove-AzureDisk returns an error:
Remove-AzureDisk : BadRequest: A disk with name
XXX is currently in use
by virtual machine YYY running within hosted service
ZZZ, deployment XYZ.
Strange thing is, I can issue the same call to Remove-AzureDisk just a few moments later and it returns successfully.
Its as if the call to Remove-AzureVM is returning too quickly. i.e. Its reporting success before the VM has been fully removed, or before the link to the disk has been removed at any rate.
Can anyone explain why this might be and also how I might work around this problem?
thanks in advance
Jamie
What's happening here is that the Disk that is stored in BLOB storage is locked when in use by a VM. You are removing the VM, but it takes a few moments for the Lease on the BLOB to release. That's why you can remove it a few moments later.
There are a few folks who have written PowerShell to break the lease, or you could use PowerShell to use the SDK (or make direct REST API calls) to check lease status.
I ended up writing a script that creates a VM, clones it, then deletes the clones. As part of that I needed to wait until the lease was released hence if you're experiencing this same problem you might want to check my blog post at http://sqlblog.com/blogs/jamie_thomson/archive/2013/11/04/clone-an-azure-vm-using-powershell.aspx as it'll have some code that might help you.
Regards
Jamie
I puzzled at this for quite a while. Ultimately, I found a different command to do what I thought I was doing with this command. I would recommend the remove-azuredatadisk command to delete a disk, as it automatically breaks the lease.
Get-AzureVM -ServiceName <servicename> -name <vmname> |Remove-AzureDataDisk -lun <lun#> -deletevhd | Update-AzureVM
It will spin for a couple of minutes, but it will give you a success/failure output at the end.
This command just does it, and doesn't give you any feedback about which drive was removed. I would recommend tossing in a get-azuredatadisk first just to be sure of what you deleted.
Get-AzureVM -ServiceName <servicename> -name <vmname> | Get-AzureDataDisk
This is related to Windows Azure: Delete disk attached to non-existent VM. Cross-posting my answer here:
I was unable to use the (2016) web portal to delete orphaned disks in my (classic) storage account. Here is a detailed walk-through for deleteing these orphaned disks with PowerShell.
PowerShell
Download and install PowerShell if you haven't already. (Install and configure Azure PowerShell.) Initial steps from this doclink:
Check that the Azure PowerShell module is available after installing:
Get-Module –ListAvailable
If the Azure PowerShell module is not listed, you may need to import it:
Import-Module Azure
Login to Azure Resource Manager:
Login-AzureRmAccount
AzurePublishSettingsFile
Retreive your PublishSettingsFile.
Get-AzurePublishSettingsFile
Get-AzurePublishSettingsFile launches manage.windowsazure.com and prompts you to download an XML file that you can be saved anywhere.
Reference: Get-AzurePublishSettingsFile Documentation
Import-AzurePublishSettingsFile and specify the path to the file just saved.
Import-AzurePublishSettingsFile -PublishSettingsFile '<your file path>'
Show and Remove Disks
Show current disks. (Reference: Azure Storage Cmdlets)
Get-AzureDisk
Quickly remove all disks. (Credit to Mike's answer)
get-azuredisk | Remove-AzureDisk
Or remove disks by name. (Credit to Remove-AzureDisk Documentation)
Remove-AzureDisk -DiskName disk-name-000000000000000000 -DeleteVHD

Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)

When I run
Get-WmiObject win32_SystemEnclosure -Computer hostname | select serialnumber
it works for both local and remote hosts.
When I do this for a list of hosts using
ForEach ($_ in gc u:\pub\list.txt) {
Get-WmiObject win32_SystemEnclosure -Computer $_ | select serialnumber | format-table -auto #{Label="Hostname"; Expression={$_}}, #{Label="Service Tag"; Expression={$_.serialnumber}}
}
it returns
Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
Check that the "Windows Management Instrumentation (WMI-In)" rule is enabled in the firewall for each remote machine.
Or in an Administrative Command/Powershell prompt run:
netsh advfirewall firewall set rule group="Windows Management Instrumentation (WMI)" new enable=yes
It might be due to various issues.I cant say which one is there in your case.
Below given reasons may be there:
DCOM is not enabled in host PC or target PC or on both.
Your Firewall or even your antivirus is preventing the access.
Any WMI related service is disabled.
Some WMI related services are as given:
Remote Access Auto Connection Manager
Remote Access Connection Manager
Remote Procedure Call (RPC)
Remote Procedure Call (RPC) Locator
Remote Registry
For DCOM setting refer:
Key: HKLM\Software\Microsoft\OLE, Value: EnableDCOM
The value should be set to 'Y' .
Your code probably isn't using a correct machine name, you should double check that.
Your error is:
Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
This is the result you get when a machine is not reachable. So the firewall suggestions are reasonable, but in this case probably not correct because you say this works:
Get-WmiObject win32_SystemEnclosure -Computer hostname
So in your case it seems when this line is executed:
Get-WmiObject win32_SystemEnclosure -Computer $_
$_ doesn't contain a proper computer name. You could check type and contents of $_. Probably there is a problem with the file contents. If the file looks right, then maybe the lines are not properly terminated. You can take a closer look using Write-Host:
ForEach ($_ in gc u:\pub\list.txt) {
Write-Host "Get-WmiObject win32_SystemEnclosure -Computer '$_'"
Get-WmiObject win32_SystemEnclosure -Computer $_ | select serialnumber | format-table -auto #{Label="Hostname"; Expression={$_}}, #{Label="Service Tag"; Expression={$_.serialnumber}}
}
I was having the same problem but only with a few machines. I found that using Invoke-Command to run the same command on the remote server worked.
So instead of:
Get-WmiObject win32_SystemEnclosure -ComputerName $hostname -Authentication Negotiate
Use this:
Invoke-Command -ComputerName $hostname -Authentication Negotiate -ScriptBlock {Get-WmiObject win32_SystemEnclosure}
If you've tried some of the suggestions in the other answers, most notably:
David Brabant's answer: confirming the Windows Management Instrumentation (WMI) inbound firewall rule is enabled
Abhi_Mishra's answer: confirming DCOM is enabled in the Registry
Then consider other common reasons for getting this error:
The remote machine is OFF
You specified an invalid computer name
There are network connectivity problems between you and the target computer
Solved.
I was running into the exact same error message when trying to execute the following script (partial) against a remote VM that was configured to be in the WORKGROUP.
Restart-Computer -ComputerName MyComputer -Authentication Default -Credential $cred -force
I noticed I could run the script from another VM in the same WORKGROUP when I disabled the firewall but still couldn't do it from a machine on the domain. Those two things along with Stackflow suggestions is what brought me to the following solution:
Note: Change these settings at your own risk. You should understand the security implications of these changes before applying them.
On the remote machine:
Make sure you re-enable your Firewall if you've disabled it during testing.
Run Enable-PSRemoting from PowerShell with success
Go into wf.msc (Windows Firewall with Advanced Security)
Confirm the Private/Public inbound 'Windows Management Instrumentation (DCOM-In)' rule is enabled AND make sure the 'Remote Address' property is 'Any' or something more secure.
Confirm the Private/Public inbound 'Windows Management Instrumentation (WMI-In)' rule is enabled AND make sure the 'Remote Address' property is 'Any' or something more secure.
Optional: You may also need to perform the following if you want to run commands like 'Enter-PSSession'.
Confirm the Private/Public inbound 'Windows Management
Instrumentation (ASync-In)' rule is enabled AND make sure the
'Remote Address' property is 'Any' or something more secure.
Open up an Inbound TCP port to 5985
IMPORTANT! - It's taking my remote VM about 2 minutes or so after it reboots to respond to the 'Enter-PSSession' command even though other networking services are starting up without problems. Give it a couple minutes and then try.
Side Note: Before I changed the 'Remote Address' property to 'Any', both of the rules were set to 'Local subnet'.
I found this blog post which suggested adding a firewall exception for "Remote Administration", and that worked for us on our Windows Server 2008 Enterprise systems.
http://mikefrobbins.com/2012/03/08/get-wmiobject-the-rpc-server-is-unavailable-exception-from-hresult-0x800706ba/
Enabling following FW rules on target system resolved the problem on Win2k16:
Windows Management Instrumentation (WMI-In)
Distribiuted Transaction Coordinator (RPC)
Distribiuted Transaction Coordinator (RPC-EPMAP)
I was having the same issue using foreach. I saved the list to $servers and used this which worked:
ForEach ($_ in $Servers) { Write-Host "Host $($_)" | Get-WmiObject win32_SystemEnclosure -Computer $_ | format-table -auto #{Label="Service Tag"; Expression={$_.serialnumber}}
}
Thought I would add that we also ran into this issue with multiple machines in our domain. I created a list of offending machines and added them all to a text file from which to run the script. I ran this from the CMD prompt using elevated privileges.
psexec #firewallFix.txt -d netsh advfirewall firewall
set rule name="Windows Management Instrumentation (WMI-In)"
profile=domain new enable=yes profile=domain
I had same issue, and for me, I was trying to use an IP Address instead of computer name.
Just adding this as one more potential solution for people finding this down the road.
I faced the similar issue on new server that I built through automated scripts via vcenter api. Looks like the "Remote Procedure Call (RPC)" service may not be running on the remote machine. you need to wait for the service to come up to use the Get-WmiObject command. Hence I simply put the script into sleep for sometime and it worked.
Below is the native PowerShell command for the most up-voted solution.
Instead of:
netsh advfirewall firewall set rule group="Windows Management Instrumentation (WMI)" new enable=yes
Use could use the slightly simpler syntax of:
Enable-NetFirewallRule -DisplayGroup "Windows Management Instrumentation (WMI-In)"
Very odd but I used the IP address (vs the hostname) and it worked for me.
Get-WmiObject -Computername MyHostName ...
[Fails: Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)]
Get-WmiObject -Computername 50.50.50.50
[Successful]
I encountered the same "Exception from HRESULT: 0x800706BA" error with get-wmiobject -computerName remoteserverName -class win32_logicaldisk. The remote server is an AWS EC2 instance in my case. The Windows server firewall has WMI ports open. SecurityGroup attached to the EC2 instance has common RPC ports (tcp/udp 135-139, 49152 - 65535) inbound allowed.
I then ran netstat -a -b |findstr remoteServerName after kick off the get-wmiobject powershell command. Turns out the command was trying hit tcp port 6402 on the remote server! After added tcp 6402 into its Security Group inbound rule, get-wmiobject works perfectly! It appears the remote server has WMI set to a fixed port!
So if you checked all usual firewall rules and stil having problem with WMI, try use netstat to identify which port the command is actually trying to hit.
I thought I would add another thing to try. If someone has multiple domains you could try using fully qualified domain names: computer1.subdomain.domain.com
Port 135 will be used by RPC client- server communication.
So Make sure that port 135 is not blocked by your local firewall. It may be one of the reasons for not working.
Here's a link that could help you: https://www.dell.com/support/kbdoc/en-in/000179474/troubleshooting-rpc-server-unavailable-errors
Turning the firewall off resolved it for me.
I was doing this mistake
ForEach ($server in $servers) {
$OS = Get-WmiObject win32_operatingsystem -ComputerName $server
}
Which, of course, couldn't be passed, because output of the server in a csv file was #{Name=hv1g.contoso.com}
I had to call the property from csv file like this $server.Name
ForEach ($server in $servers) {
$OS = Get-WmiObject win32_operatingsystem -ComputerName $server.Name
}
It fixed my issue.
I just came to the exact same issue and found the answer here: http://powershellcommunity.org/Forums/tabid/54/aft/7537/Default.aspx
I had space characters at the end of each line the input file. If your file does too, just remove them and your script should work.