VMware Cloud Community
qwert1235
Enthusiast
Enthusiast
Jump to solution

Script to export/import Alarms between VC or synchronize alarms between 2 Virtual Centers

Hello:

I am wonder if there is a way to synchronize alarms between 2 Virtual Centers?

Or for example, how to export all alarms from one VC and import them to another? Is it possible?

Any help would be really appreciated.

Thanks a lot!

1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

The following script will remove all alarms on al visible entities

$alarmManager = Get-View AlarmManager
$alarms = $alarmManager.GetAlarm($null)
$alarms | %{
	$alarm = Get-View $_
	$alarm.RemoveAlarm()
}

Note that this not remove the alarms on hidden entities like vm, host and datacenters.

And please test in a non-production environment first !

There is no way to get a deleted alarm back.

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

Reply
0 Kudos
49 Replies
jcwuerfl
Hot Shot
Hot Shot
Jump to solution

humm. not sure how to export/import really but here may be an idea. Have your vCenter alarms run powershell scripts and keep those powershell scripts synchronized between the two virtual center servers?

http://blogs.vmware.com/vipowershell/2009/09/how-to-run-powercli-scripts-from-vcenter-alarms.html

Or are you worried more about redundancy for vCenters? have you looked at Linked mode at all with vCenter? or vCenter Heartbeat

Reply
0 Kudos
qwert1235
Enthusiast
Enthusiast
Jump to solution

Thanks, but it's not what I want.

I built 1 VC and need to build another one with the same settings. I know how to recreate the same clusters, folders and etc... but have problems with alarms.

I just want my VC2 to have the same alarms and settings for alarms as VC1. I can install alarms by script, but hoped that there is way to export/import them; at that case these is no need to modify script for alarms installation when/if we decided to change alarms.

Another words, I want my VC to have the same alarms as "golden" VC.

Any other ideas?

Thanks

Reply
0 Kudos
aevrov
VMware Employee
VMware Employee
Jump to solution

Hi qwert1235,

Here is one solution to your problem. When you want to synch the alarms on VC2:

1. Delete all alarms on VC2.

2. For each alarm on VC1:

2.1. Get its AlarmSpec object and use it to create a corresponding alarm on VC2. This can be done with GetAlarm and CreateAlarm methods of the AlarmManager. (You may face some difficulty if you have alarms that are associated with an entity other than the inventory root. In this case you have to somehow map the entity from VC1 to entity from VC2 in order to make an exact copy of the alarms configuration. You can implement some logic for traversing the inventory if you need to maintain such a mapping.)

Hope this helps. Let me know if you have any difficulty scripting this.

Regards,

-Angel

LucD
Leadership
Leadership
Jump to solution

That is a good idea, provided your vCenters can talk with each other.

See also my Alarms – Moving them around post.

With the DeleteOriginal switch you could implement the move as a copy.

But what if you need to copy these specs to a portable medium (a file in other words) to transfer them from VC1 to VC2 ?

PS serialization and deserialization methods will not allow you to read in the spec and use it in VC2 to create the alarm.

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

aevrov
VMware Employee
VMware Employee
Jump to solution

The VC's don't necessarily need to talk to each other - PowerCLI needs to talk to both of them, which would be the common case.

You can use the .NET serialization if you need to serialize the specs (this would be more difficult but it's possible).

Regards,

-Angel

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I have been playing with serialization/deserialization for a while now (the .Net serialization methods included) and it won't work.

The process changes the typename as you probably know.

I would be more than happy if you could provide a working example of such a script.

Read a spec, serialize it, deserialize it on the other side and use the spec to create a new entity.

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
qwert1235
Enthusiast
Enthusiast
Jump to solution

Guys,

Thank you very much for your input!!!

My VCs, will not be to able talk to each other, neither (sometimes) my CLI will not be able to talk to both VCs at the same time. The best option would be to import alarms from VC1 into something like file and export/apply later on to VC2, but does not look like it will work.

Looks like the path should be like that:

1. Delete all alrms on VC2

2. Create new alarms on VC2 identical alarms on VC1.

I think, it’s should be doable.

I know (a little bit) how to create alarms and how to delete them.

For example, I know how to delete specific alarm (LucD helped me a lot last time):

$alarmManager = Get-View -Id 'AlarmManager-AlarmManager'

$entityView = Get-View (Get-Folder -Name "Datacenters").ID

$alarmMoRefList = $alarmManager.GetAlarm($entityView.MoRef)

$alarmViewList = $alarmMoRefList | foreach { Get-View $_}

$alarmToDelete = $alarmViewList | where {$_.Info.Name -eq "Name of alrm"}

if ($alarmToDelete -ne $null){$alarmToDelete.RemoveAlarm()}

but how I can delete ALL alarms defined in my Datacenter at once?

Can you please help me to figure out how to delete all alarms that already in my “alarmMoRefList”?

Thanks a lot!

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The following script will remove all alarms on al visible entities

$alarmManager = Get-View AlarmManager
$alarms = $alarmManager.GetAlarm($null)
$alarms | %{
	$alarm = Get-View $_
	$alarm.RemoveAlarm()
}

Note that this not remove the alarms on hidden entities like vm, host and datacenters.

And please test in a non-production environment first !

There is no way to get a deleted alarm back.

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
qwert1235
Enthusiast
Enthusiast
Jump to solution

Luc,

Thanks a lot!

It does work exactly as I need.

Thanks again.

P.S. I might bother you for help to withe one type of alarm I have problem to create (it’s hardware monitoring alarm – like “Host hardware power status”)

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Sure, open a new thread or drop me an email.

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
aevrov
VMware Employee
VMware Employee
Jump to solution

Hi Luc,

I also played with the serialization for a while. Since I had some strange problems with the .net serialization, I made a script that converts the alarm specification deserialized with Import-Clixml to the original object type.Here's the script:

function ExportAlarm(){
	Connect-VIServer $serverToExportFrom -User '###'-Password '###'
	$alarmToExport = Get-AlarmDefinition $alarmToExportName
	$a = Get-View -Id $alarmToExport.Id
	$a.Info | Export-Clixml -Path $fileName -Depth ( \[System.Int32\]::MaxValue )
}

function ImportAlarm {

	Connect-VIServer $serverToImportTo -User '###'-Password '###'
	
	$deserializedAlarmInfo = Import-Clixml -Path $fileName
	$importedAlarmInfo = ConvertFromDeserialized( $deserializedAlarmInfo )
	$entity = Get-Folder -NoRecursion
	
	$alarmManager = Get-View -Id "AlarmManager"
	$alarmManager.CreateAlarm($entity.Id, $importedAlarmInfo)
}

# This function converts a Powershell object deserialized from xml (with Import-Clixml) to its original type (that has been previously serialized with Export-Clixml)
# The function will not work with all .NET types. It is currently tested only with the Vmware.Vim.AlarmInfo type.
function ConvertFromDeserialized {
	param(
		$deserializedObject
	)
	
	if($deserializedObject -eq $null){
		return $null
	}
		
	$deserializedTypeName = ($deserializedObject | Get-Member -Force | where { $_.Name -eq "psbase" } ).TypeName;
	
	if($deserializedTypeName.StartsWith("Deserialized.")) {
		$originalTypeName = $deserializedTypeName.Replace("Deserialized.", "")
		$result = New-Object -TypeName $originalTypeName
		$resultType = $result.GetType()
		
		if($resultType.IsEnum){
			$result = \[Enum\]::Parse($resultType, $deserializedObject, $true)
			return $result
		}
		
		$deserializedObject | Get-Member | % { 
			if($_.MemberType -eq "Property") {
				$resultProperty = $resultType.GetProperty($_.Name)
				if($resultProperty.CanWrite){
					$propertyValue = ( Invoke-Expression ('$deserializedObject.' + $_.Name) | % { ConvertFromDeserialized( $_ ) } ) 
					if($propertyValue -and $resultProperty.PropertyType.IsArray ) {
						if($propertyValue.GetType().IsArray){
							# convert the elements
							$elementTypeName = $resultProperty.PropertyType.AssemblyQualifiedName.Replace("\[\]", "")
							$elementType = \[System.Type\]::GetType($elementTypeName)
							$array = \[System.Array\]::CreateInstance($elementType, $propertyValue.Count)
							for($i = 0; $i -lt $array.Length; $i++){
								$array\[$i\] = $propertyValue\[$i\]
							}
							$propertyValue = $array
						} else {
							$elementTypeName = $resultProperty.PropertyType.AssemblyQualifiedName.Replace("\[\]", "")
							$elementType = \[System.Type\]::GetType($elementTypeName)
							$array = \[System.Array\]::CreateInstance($elementType, 1)
							$array\[0\] = $propertyValue
							$propertyValue = $array
						}
					}
					$resultProperty.SetValue($result, $propertyValue, $null)
				}
			}
		} 
	} else {
		$result = $deserializedObject
	}
	
	return $result	
}

# Example of exporting and importing an alarm - uncomment the desired action
# This script allows you to export an alarm from a vCenter server and import it to another one, whus maintaining a "mirror" of the original alarm
$fileName = "d:\AlarmDefinition.xml"
$serverToExportFrom = "vc41-ga.pc"
$serverToImportTo = "10.23.113.20"
$alarmToExportName = "t2zzzzzzzzz"
ExportAlarm
#ImportAlarm

qwert1235
Enthusiast
Enthusiast
Jump to solution

Luc,

One more question.

This script, as you wrote, will remove all alarms on all objects.

How should I adjust the script to remove alarms that defined only on specific object?

For example, I want to remove all alarms that are defined on VC level only, but leave untouched all other alarms (that are define on Datacenter,Cluster, ESX and etc. level).

Is it possible?

Thanks a lot!

Reply
0 Kudos
aevrov
VMware Employee
VMware Employee
Jump to solution

Hi,

You should replace line 2 in Luc's script ("$alarms = $alarmManager.GetAlarm($null") with these 2 lines:

$inventoryRoot = Get-Folder -NoRecursion

$alarms = $alarmManager.GetAlarm($inventoryRoot.Id)

Regards,

-Angel

Reply
0 Kudos
qwert1235
Enthusiast
Enthusiast
Jump to solution

Angel,

Thanks a lot!

Actually all I needed to do is add "NoRecursion" to the following line $entityView = Get-View (Get-Folder -Name "Datacenters" -NoRecursion).ID

again,

Thank you very much!!!

Reply
0 Kudos
aevrov
VMware Employee
VMware Employee
Jump to solution

Hi,

This will work for the most cases. But note that on older VC versions, the name of the root folder is different (cant remember the exact name though). You can omit the folder name for an all-case solution.

Regards,

-Angel

Reply
0 Kudos
RS_1
Enthusiast
Enthusiast
Jump to solution

Hi, i found that you can used deserialized AlarmInfo without conversion with this method (attached ps1)

It works () but maybe i'm missing something ?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You're assuming that all alarms are all defined on the rootfolder, whcih is not the case.

And I think you're overlooking the fact that the alarm import will use the same MoRefs for the alarm itself and for the entity on which it is defined, on the import side. While the root-folder might look to be 'Folder-group-d1' all the time, you can't be sure of this. And it will definitely not work for alarms defined on other entities.

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
RS_1
Enthusiast
Enthusiast
Jump to solution

Thanks Luc, i must have specify that it was only for root alarm in my case.

To avoid MoRefs issues, i was thinking about filtering on name,Description,Enabled,Expression,Action before xml export.

Do you think it could do the trick ?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ok, I see.

Afaik, there are no MoRefs in the Actions nor Expressions.

So that shouldn't be a problem.

Another point to remember are the MetricAlarmExpression objects.

They use the id for metric which is not necessarily the same on the target vCenter.

Similar remark for the EventAlarmExpression object.

Some of these events can be EventEx or ExtendedEvent events and they rely on the extensions (Converter,Update Manager...) installed on a vCenter. You would first have to make sure that your target vCenter has the same extensions as your source vCenter.

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference