I currently get a spreadsheet of system names and the values, many of which are not annotations.
I pull out the system names, and the value I need to add/update, massage that data as needed (mainly fixing the system name) and then run this script.
<code>
Import-CSV .\data.csv |for-each-object
{
set-annotation -Entity $_,vmname -customattribute "attrib-name" -value $_.value
}
</code>
I'd like to simplify what I do, and set all of the annotations from one spreadsheet, so I am just massaging it once, instead of once per annotation.
TIA!!
~Jahn
Ok, got it.
In that case try this slightly changed script
foreach($row in (Import-CSV .\data.csv)){
$vm = Get-VM -Name $row.'System Name'
foreach($prop in ($row | gm -MemberType NoteProperty | where{$_.Name -ne 'System Name'} | select -ExpandProperty Name)){
Try{
$ca = Get-CustomAttribute -TargetType VirtualMachine -Name $prop -ErrorAction Stop
}
Catch{
$ca = New-CustomAttribute -TargetType VirtualMachine -Name $prop -Confirm:$false
}
Set-Annotation -CustomAttribute $ca -Value $row."$prop" -Entity $vm -Confirm:$false
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Unfortunately the Set-Annotation cmdlet only accepts 1 custom attribute per call.
So I don't think what you want to do is possible.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks for the response.
SInce set-annotation won't take multiple attributes, how about cycling through the systems names from column 1, doing each of the following columns containing 8 different annotations?
That's possible, can you show a sample row of the file?
Do you have 1 or more custom attributes on a row in the file?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
The current csv for the above script is very simple, for this one, "owner".
Header 1 | Header 2 |
---|---|
VMname | Value |
servername* | First@Last.domain.com |
The spreadsheet that I get and massage is like this
Header 1 | Header 2 | Header 3 | Header 4 | Header 5 | |
---|---|---|---|---|---|
System Name | owner | created | tier | Managed-by | |
servername.domain.com |
| 01/02/2018 | 3 | team-1 |
Starting from that 2nd CSV you could do something like this
$vm = Get-VM -Name $row.'System Name'
foreach($prop in ($row | gm -MemberType NoteProperty | where{$_.Name -ne 'System Name'} | select -ExpandProperty Name)){
Get-Annotation -Entity $vm -Name $prop |
Set-Annotation -Value $row."$prop" -Confirm:$false
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
TY! I'm gonna try this out pretty quick
Well bummer, this didn't work. Here is the first and second error, there are many more, they were all the rest of the other annotations.
<CODE>
Set-Annotation : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input
and its properties do not match any of the parameters that take pipeline input.
At C:\Users\user1\Desktop\scripts\powercli\connect\annotations\one-script\set-anno-one-scr.ps1:10 char:6
+ Set-Annotation -Value $row."$prop" -Confirm:$false
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (CreatedBy:JS:PSObject) [Set-Annotation], ParameterBindingException
+ FullyQualifiedErrorId : InputObjectNotBound,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetAnnotation
Set-Annotation : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input
and its properties do not match any of the parameters that take pipeline input.
At C:\Users\user1\Desktop\scripts\powercli\connect\annotations\one-script\set-anno-one-scr.ps1:10 char:6
+ Set-Annotation -Value $row."$prop" -Confirm:$false
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (CreatedOn:11/30/2011 22:00:PSObject) [Set-Annotation], ParameterBindingException
+ FullyQualifiedErrorId : InputObjectNotBound,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetAnnotation
</CODE>
Do these Custom Fields already exist or are they new, and to be created?
Which PowerCLI version are you using?
And can you include the script as you are using it?
And a sample line from the CSV you are using?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yes, I update them with the script at the top of this chain, albeit one at a time.
VMWARE PowerCLi 10.0.0 build 7895300
foreach($row in (Import-CSV .\data.csv)){
$vm = Get-VM -Name $row.'System Name'
foreach($prop in ($row | gm -MemberType NoteProperty | where{$_.Name -ne 'System Name'} | select -ExpandProperty Name)){
Get-Annotation -Entity $vm -Name $prop |
Set-Annotation -Value $row."$prop" -Confirm:$false
}
}
This is cleaned up, removing "personal" data. It is from notepad, after openeing the csv in it.
System Name,Program,Project Code,(StorageCode),(ServerCode),Environment,Managed By,Location,Owner,CreatedBy,CreatedOn
server1*,pr1,123456,code1,NULL,Tier 1,E3,dc1,"name,name","name,name",1/2/2018
server2*,pr2,234567,code2,code3,Tier 1,E4,dc1,"name,name","name,name",1/3/2017
You have 'System Name' values with an asterisk in there, those can return more than 1 VM.
Is that the intention?
The script I gave is not foreseen for that I'm afraid.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yes, the names of the systems in ESX unfortunately do not follow a convention, sometimes it is FQDN, sometimes not, can be in be different domain also. I have found that using the wildcard after the name gets it to find the systems. This has not been a problem for me for any other scripts I run.There are not duplicates of the names.
I tried setting the name so it is exactly the same as the VM, without the asterisk, and I got the same error.
Ok, got it.
In that case try this slightly changed script
foreach($row in (Import-CSV .\data.csv)){
$vm = Get-VM -Name $row.'System Name'
foreach($prop in ($row | gm -MemberType NoteProperty | where{$_.Name -ne 'System Name'} | select -ExpandProperty Name)){
Try{
$ca = Get-CustomAttribute -TargetType VirtualMachine -Name $prop -ErrorAction Stop
}
Catch{
$ca = New-CustomAttribute -TargetType VirtualMachine -Name $prop -Confirm:$false
}
Set-Annotation -CustomAttribute $ca -Value $row."$prop" -Entity $vm -Confirm:$false
}
}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Was this supposed to try and create a custom attribute? I would not want that..... Here is first three errors, the errors repeats for the other attributes.
The script did not update any fields.
<code>
New-CustomAttribute : 5/10/2018 7:47:34 AM New-CustomAttribute The name 'CreatedBy' already exists.
At c:\script\run.ps1:15 char:15
+ ... $ca = New-CustomAttribute -TargetType VirtualMachine -Name $pro ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [New-CustomAttribute], DuplicateName
+ FullyQualifiedErrorId : Client20_InventoryServiceImpl_NewAnnotation,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewCustomAttribute
New-CustomAttribute : 5/10/2018 7:47:34 AM New-CustomAttribute The name 'CreatedBy' already exists.
At C:\scripts\run.ps1:15 char:15
+ ... $ca = New-CustomAttribute -TargetType VirtualMachine -Name $pro ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [New-CustomAttribute], DuplicateName
+ FullyQualifiedErrorId : Client20_InventoryServiceImpl_NewAnnotation,VMware.VimAutomation.ViCore.Cmdlets.Commands.NewCustomAttribute
Set-Annotation : Cannot validate argument on parameter 'CustomAttribute'. The argument is null. Provide a valid value for the argument, and then try
running the command again.
At C:\scripts\run.ps1:19 char:39
+ Set-Annotation -CustomAttribute $ca -Value $row."$prop" -Entity ...
+ ~~~
+ CategoryInfo : InvalidData: (:) [Set-Annotation], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetAnnotation
</code>
That is strange, the Try-Catch first tries to get the Custom Attribute, only when it does not exist, will the script create it.
So you probably already have a Custom Attribute by that name, but probably not assigned to that TargetType.
Do a Get-CustomAttribute -Name 'CreatedBy', and check what the TargetType says.
If blank, leave out the TargetType parameter from the Custom Attribute cmdlets.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Key Name TargeType
--- ---- ---------------
8 CreatedBy
202 CreatedBy
Is it normal to see 2, did I create one?
I removed the targettype from the script.
I changed the catch to tell me the custom attribute does not exist, though I know the ones I have in the csv are valid.
I also changed the column 1 header to Server, so that spaces can't be an issue.
<code>
foreach($row in (Import-CSV .\data.csv)){
$vm = Get-VM -Name $row.'Server'
foreach($prop in ($row | gm -MemberType NoteProperty | where{$_.Name -ne 'Server'} | select -ExpandProperty Name)){
Try{
$ca = Get-CustomAttribute -Name $prop -ErrorAction Stop
}
Catch{
write-host The custom attribute does not exist.
}
Set-Annotation -CustomAttribute $ca -Value $row."$prop" -Entity $vm -Confirm:$false
}
}
</code>
<error>
Set-Annotation : Cannot convert 'System.Object[]' to the type 'VMware.VimAutomation.ViCore.Types.V1.AnnotationManagement.CustomAttribute' required by
parameter 'CustomAttribute'. Specified method is not supported.
At C:\scripts\run.ps1:18 char:39
+ Set-Annotation -CustomAttribute $ca -Value $row."$prop" -Entity ...
+ ~~~
+ CategoryInfo : InvalidArgument: (:) [Set-Annotation], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetAnnotation
</error>
There are seemingly 2, but they are not same in my opinion.
So $ca is an array with 2 entries, and that is why the Set-Annotation fails.
Remove the custom attribute with the Remove-CustomAttribute, but use the Id parameter instead of the Name
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
When I use powercli, I connect to 2 vcenter hosts, one internal, and one dmz. That is why there was 2 for the same name. When I restarted my session, and I only connected to one host, the script worked!
Below is the final script that worked for me.
Would it be easy to get the output to be like this:
server created owner backup
-------- ---------- ------- ----------
server1 1-2018 name,name virtual
server2 1-2018 name,name tape
<code>
foreach($row in (Import-CSV .\data.csv)){
$vm = Get-VM -Name $row.'Server'
foreach($prop in ($row | gm -MemberType NoteProperty | where{$_.Name -ne 'Server'} | select -ExpandProperty Name)){
Try{
$ca = Get-CustomAttribute -Name $prop -ErrorAction Stop
}
Catch{
write-host The custom attribute does not exist.
}
Set-Annotation -CustomAttribute $ca -Value $row."$prop" -Entity $vm -Confirm:$false
}
}
</code>
Thank you so much!!
Try like this
$report = foreach($row in (Import-CSV .\data.csv)){
$vm = Get-VM -Name $row.'System Name'
$obj = [ordered]@{
Server = $vm.Name
}
foreach($prop in ($row | gm -MemberType NoteProperty | where{$_.Name -ne 'System Name'} | select -ExpandProperty Name)){
Try{
$ca = Get-CustomAttribute -TargetType VirtualMachine -Name $prop -ErrorAction Stop
}
Catch{
write-host "The custom attribute $prop does not exist."
}
Set-Annotation -CustomAttribute $ca -Value $row."$prop" -Entity $vm -Confirm:$false
$obj.Add($prop,$row."$prop")
}
New-Object PSObject -Property $obj
}
$report | Export-Csv .\report.csv -NoTypeInformation -UseCulture
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference