VMware Cloud Community
simonwa
Contributor
Contributor

custom attributes with dates

I've tried so many different ways to read a custom attribute which is a date and then set-annotation or set-customattribute for another field with another date and nothing seems to work. Nothing seems to read the LastPowerOff date field. consistently returning blank.

any suggestions please?

foreach ($VM in $VMs) {
Write-Host "Processing VM: $($VM.Name)"

# Get the custom attribute 'lastpoweroff'
#$lastPowerOff = $VM.ExtensionData.CustomValue | Where-Object {$_.Key -eq 'LastPowerOff'} | Select-Object -ExpandProperty Value
$lastPowerOff = (($VM).CustomFields | Where {$_.Key -eq "LastPowerOff"}).value

Write-Host "LastPowerOff: $lastPowerOff"

# Check if the 'lastpoweroff' date is greater than 180 days ago
if ($lastPowerOff -gt (Get-Date).AddDays(-180)) {
Write-Host "Adding decomdate attribute for VM: $($VM.Name)"

# Calculate the decommission date by adding 30 days to the current date
$decomDate = (Get-Date).AddDays(30)
Write-Host "decomdate: $decomDate"

# Set the custom attribute 'decomdate' with the calculated decommission date
#Set-CustomAttribute -Entity $VM -Name 'decomdate' -Value $decomDate
Set-Annotation -Entity $VM -Name 'DecomDate' -Value $decomDate
Write-Host "decomdate attribute added for VM: $($VM.Name)"
}
}

0 Kudos
13 Replies
LucD
Leadership
Leadership

What exactly do you have in the LastPowerOff CA?

Note that the Value will be returned as String, to perform actions on that date you probably have to first cast the String to A DateTime value.
To convert a String to a DateTime also depends on what Culture is defined in your PS session.


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

0 Kudos
simonwa
Contributor
Contributor

Hi Luc,

i have datetime like this, 30-09-2022 21:11:22.

No culture set but it's UK default.

Something like this then?

# Get the custom attribute 'lastpoweroff'
$lastPowerOffString = (($VM).CustomFields | Where {$_.Key -eq "LastPowerOff"}).value
$lastPowerOffDate = [datetime]::parseexact($lastPowerOffString, 'dd-MM-yyyy HH:mm:ss', $null)

Write-Host "LastPowerOffDate: $lastPowerOffDate"

 

Thank you

0 Kudos
LucD
Leadership
Leadership

An easy check would be a cast

[DateTime]"30-09-2022 21:11:22"

Does that return a valid DateTime object?


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

0 Kudos
simonwa
Contributor
Contributor

the parse works, thanks.

$lastpoweroff = [datetime]::parseexact('30-09-2022 21:11:22','dd-MM-yyyy HH:mm:ss', $null)

echo $lastPowerOff

30 September 2022 21:11:22

Getting the CA in the first place seems to be the issue.

$lastPowerOffString = $VM.ExtensionData.CustomValue | Where-Object {$_.Key -eq 'LastPowerOff'} | Select-Object -ExpandProperty Value #comes back blank Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime."

$lastPowerOffString = (($VM).CustomFields | Where {$_.Key -eq "LastPowerOff"}).value #comes back blank Exception calling "ParseExact" with "3" argument(s): "String was not recognized as a valid DateTime."

0 Kudos
LucD
Leadership
Leadership

Did you also try with

[DateTime]($vm.CustomFields['LastPowerOff'])


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

0 Kudos
simonwa
Contributor
Contributor

sorry i don't know how that syntax fits in to what i'm doing.

0 Kudos
LucD
Leadership
Leadership

That returns a DateTime object that you can use to make the comparison.

Note that I changed your comparison, if you want to find a power off more than 180 days ago, the operator should be -lt afaik

foreach ($VM in $VMs) {
    Write-Host "Processing VM: $($VM.Name)"
    
    # Get the custom attribute 'lastpoweroff'
    $lastPowerOff = [DateTime]($vm.CustomFields['LastPowerOff'])
    
    Write-Host "LastPowerOff: $lastPowerOff"
    
    # Check if the 'lastpoweroff' date is more than 180 days ago
    if ($lastPowerOff -lt (Get-Date).AddDays(-180)) {
        Write-Host "Adding decomdate attribute for VM: $($VM.Name)"
    
        # Calculate the decommission date by adding 30 days to the current date
        $decomDate = (Get-Date).AddDays(30)
        Write-Host "decomdate: $decomDate"
    
        # Set the custom attribute 'decomdate' with the calculated decommission date
        #Set-CustomAttribute -Entity $VM -Name 'decomdate' -Value $decomDate
        Set-Annotation -Entity $VM -Name 'DecomDate' -Value $decomDate
        Write-Host "decomdate attribute added for VM: $($VM.Name)"
    }
}
    
    




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

0 Kudos
simonwa
Contributor
Contributor

thanks very much for your help but this is the output

Set-Annotation : Cannot bind parameter 'Entity'. Cannot convert the "VMware.Vim.VirtualMachine" value of type "VMware.Vim.VirtualMachine" to type
"VMware.VimAutomation.ViCore.Types.V1.Inventory.InventoryItem".
At C:\Users\t0wallas\Documents\WindowsPowerShell\Scripts\MyTagHouseKeeping.ps1:42 char:32
+ Set-Annotation -Entity $VM -Name 'DecomDate' -Value $decomDat ...
+ ~~~
+ CategoryInfo : InvalidArgument: (:) [Set-Annotation], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetAnnotation

Tags (1)
0 Kudos
LucD
Leadership
Leadership

I didn't check the rest of your script, but that is not how Set-Annotation works.
That cmdlet has no Name parameter.
You will have to get the Custom Attribute you want to update with the Get-CustomAttribute cmdlet.

Provided that CA already exists, you could do

$ca = Get-CustomAttribute -Name DecomDate'
Set-Annotation -Entity $vm -CustomAttribute $ca -Value $decomDate 


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

0 Kudos
simonwa
Contributor
Contributor

Set-Annotation : Cannot bind parameter 'Entity'. Cannot convert the "VMware.Vim.VirtualMachine" value of type "VMware.Vim.VirtualMachine" to type
"VMware.VimAutomation.ViCore.Types.V1.Inventory.InventoryItem".
At C:\Users\Scripts\MyHouseKeeping.ps1:43 char:80
+ ... nnotation -CustomAttribute $decomDateCA -Value $decomDate -Entity $VM
+ ~~~
+ CategoryInfo : InvalidArgument: (:) [Set-Annotation], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetAnnotationSet-Annotation : Cannot bind parameter 'Entity'. Cannot convert the "VMware.Vim.VirtualMachine" value of type "VMware.Vim.VirtualMachine" to type
"VMware.VimAutomation.ViCore.Types.V1.Inventory.InventoryItem".
At C:\Users\t0wallas\Documents\WindowsPowerShell\Scripts\MyTagHouseKeeping.ps1:43 char:80
+ ... nnotation -CustomAttribute $decomDateCA -Value $decomDate -Entity $VM
+ ~~~
+ CategoryInfo : InvalidArgument: (:) [Set-Annotation], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetAnnotation

0 Kudos
LucD
Leadership
Leadership

Which PowerCLI version are you running?
Do a

Get-Module -Name VMware.PowerCLI -ListAvailable


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

0 Kudos
simonwa
Contributor
Contributor

I was using the top ones, tried again after updating tp the latest below.

ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 11.3.0.... VMware.PowerCLI
Manifest 12.7.0.... VMware.PowerCLI


ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Manifest 13.1.0.... VMware.PowerCLI

0 Kudos
LucD
Leadership
Leadership

Having multiple versions installed causes issues.
I suggest removing all of them and doing a fresh install.


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

0 Kudos