Using Generalized Time in custom field - powershell

We are looking to add a couple of date fields to our Active Directory schema in 2008 R2 to help facilitate a bit of automation. In particular adding in a hireDate field that is populated automatically from an import.
This all works as expected in our test environment, however I am curious if there is a way to enhance the display of this custom attribute when it comes to dates.
The hireDate field is set as a Syntax of Generalized Time to match the native fields such as whenCreated.
However, when placing a date in to hireDate, it formats this much different than whenCreated for the display
> $user = Get-ADUser MyUser -Properties whenCreated,hireDate
> $user
-- snip --
hireDate : {19870301070000.0Z}
whenCreated : 8/28/2014 12:24:42 PM
If I inspect the MemberType of these properties, they are different too even though they are both Generalized Time
$user | Get-Member -MemberType Properties
TypeName: Microsoft.ActiveDirectory.Management.ADUser
Name MemberType Definition
---- ---------- ----------
hireDate Property Microsoft.ActiveDirectory.Management.ADPropertyValueCollection hireDate {get;set;}
whenCreated Property System.DateTime whenCreated {get;}
Is there a proper way to create a custom attribute as a DateTime or are we limited with the way to create these attributes?

hireDate is a collection. To get the actual value you need .hireDate[0] or .hireDate | Select-Object -First 1. And if PowerShell doesn't parse a Generalize-Time timestamp for you (hireDate isn't a standard attribute after all) you need to do it yourself.
$fmt = "yyyyMMddHHmmss.f'Z'"
$culture = [Globalization.CultureInfo]::InvariantCulture
Get-ADUser MyUser -Properties whenCreated,hireDate |
Select-Object -Property *, #{n='hireDate';e={
[DateTime]::ParseExact($_.hireDate[0], $fmt, $culture)
}} -Exclude hireDate

Related

Inconsistent result from Get-CsOnlineUser

The property OnlineVoiceRoutingPolicy returned in powershell is inconsistent. Either i'm doing something wrong with when selecting based on identity, or theres a bug i'm unaware of.
When not selecting from identity i get something like this:
Get-CsOnlineUser | Select-Object -Property OnlineVoiceRoutingPolicy, UserPrincipalName
OnlineVoiceRoutingPolicy UserPrincipalName
------------------------ -----------------
DK user1#test.it
...//other similar users
But when i use the -Identity argument:
Get-CsOnlineUser -Identity user1#test.it | Select-Object -Property OnlineVoiceRoutingPolicy, UserPrincipalName
OnlineVoiceRoutingPolicy UserPrincipalName
------------------------ -----------------
user1#test.it
This happens fo all users, if i get the collection of users, OnlineVoiceRoutingPolicy is correctly set, but if i get a specific user, it's blank.
Any suggestions as to why this happens ?

powershell Extract part of output

Good day,
I have a script that I wrote that gathers computer information from AD.
One specific property I am gathering is the MemberOf. When I run the script it outputs the full path for the group that computer account is a member of. I want just the group name. Please see below:
get-qadcomputer -identity $computer | format-list -property Name, AccountIsDisabled, whenCreated, whenChanged, Description, AllMemberOf, ParentContainerDN
My output looks like:
Name : SALESWS3381FPO
AccountIsDisabled : False
whenCreated : 3/7/2018 9:44:07 AM
whenChanged : 12/24/2018 4:18:04 AM
Description : BLDG 589 FLR 2 RM 567
AllMemberOf : {CN=SALES-ADOBEPRO-Win10_COMPUTERS,OU=Security Groups,OU=Groups,OU=Site Specific
OUs,OU=sales,DC=example,DC=com}
ParentContainerDN : OU=Bldg 589,OU=Desktops,OU=sales,DC=example,DC=com
So, for AllMemberOf, I want it to say AllMemberOf: SALES-ADOBEPRO-Win10_Computers
We are running Active Roles Client on our machines.
You could use the a simple regular expression to get the value of the group from the complete string.
By using a calculated property to your format-list, you can extract and keep only the group name.
#{n='AllMemberOf ';e={$_.AllMemberOf -replace "(CN=)(.*?),.*",'$2'}}
Here's your modified code sample applying that calculated property:
get-qadcomputer -identity $computer | format-list -property Name, AccountIsDisabled, whenCreated, whenChanged, Description, #{n='AllMemberOf ';e={$_.AllMemberOf -replace "(CN=)(.*?),.*",'$2'}}, ParentContainerDN
References :
4sysops - Add a calculated property with Select-Object in Powershell
StackOverflow — How can I use Regex to pull just the CN from a Distinguished Name with PowerShell

powershell convert the date property to string when using ConvertTo-Json

I'd like to get all Hyper-V VM information from Get-VM cmdlet as below:
Get-Vm | Select-Object * | ConvertTo-Json
Where the CreationTime in each VM dictionary looks like \/Date(-11644473600000)\/", in the output
How can I make it look like this format 2017/11/29 16:09:00 in the output json?
When I guess it is the number of Epoch timestamp, I found it sometimes a negative number.
I found some articles taking about this issue which take Get-Date for example, but in my case it is a property in Get-VM that I am not sure if a faster way to convert the date property without long script to parse the output.
To select a Property based on an user defined Expression one can define them in Select-Object the following way:
Get-VM | Select-Object -Property #{Name="ReadableCreationTime"; Expression={Get-Date $_.CreationTime}}, *
This selects the user defined property ReadableCreationTime and all other properties (*).
Now, you want to exclude the original CreationTime as it is a) hard to read and b) redundant to ReadableCreationTime. This can be done using the -ExcludeProperty parameter:
Get-VM | Select-Object -Property #{Name="ReadableCreationTime"; Expression={Get-Date $_.CreationTime}}, * -ExcludeProperty CreationTime
...And pipe the result to ConvertTo-Json
Keep in mind that while reading the resulting json, you have to parse the date, because it is just a string, not a valid Date value.

How to remove curly brackets from the PowerShell output

This is regarding AWS Certificate manager:
Get-ACMCertificatelist | Get-ACMCertificateDetail | Select -ExpandProperty renewalsummary | Where-object {$_.renewalStatus -ne "Success"}
Following is the output and I want to remove those curly brackets:
DomainValidationOptions RenewalStatus
----------------------- -------------
{Certificate1} PENDING_AUTO_RENEWAL
{certificate2} PENDING_AUTO_RENEWAL
The object in question is actually giving you an array for the DomainValidationOptions part, which can contain more than one value.
| Select #{n="DomainValidationOptions";e={($_.DomainValidationOptions -join ",")}},RenewalStatus
putting this on the end of your query will replace the DomainValidationOptions with a comma-separated string instead of an array, but keep the name, in cases where there's only one option this technically just converts it to a string.
Those are automatically added when converting a collection to a string in the formatting cmdlets. You can format the objects yourself to get rid of them.
You can specify calculated properties for each of the properties of DomainValidationOptions that you want to drill down into.
Step 1) Discover Properties
Pipe DomainValidationOptions to Get-Member -MemberType Property to see what properties you're going to be working with:
Get-ACMCertificateList |
Get-ACMCertificateDetail |
Select -ExpandProperty RenewalSummary |
Select -ExpandProperty DomainValidationOptions |
Get-Member -MemberType Property
TypeName: Amazon.CertificateManager.Model.DomainValidation
Name MemberType Definition
---- ---------- ----------
DomainName Property string DomainName {get;set;}
ValidationDomain Property string ValidationDomain {get;set;}
ValidationEmails Property System.Collections.Generic.List[string] ValidationEmails {get;set;}
ValidationStatus Property Amazon.CertificateManager.DomainStatus ValidationStatus {get;set;}
Step 2) Make Request
For the sake of example, lets say that we only want to retrieve DomainName and ValidationDomain. We would add two calculated properties for each of these properties, and then just do a regular select for RenewalStatus on the RenewalSummary object:
Get-ACMCertificateList |
Get-ACMCertificateDetail |
Select -ExpandProperty RenewalSummary |
Where-object {$_.RenewalStatus -ne "Success"} |
Select #{N='DomainName';E={$_.DomainValidationOptions.DomainName}}, `
#{N='ValidationDomain';E={$_.DomainValidationOptions.ValidationDomain}}, `
RenewalStatus
Example Output:
DomainName ValidationDomain RenewalStatus
---------- ---------------- -------------
*.subdomain.mydomain.com mydomain.com PENDING_AUTO_RENEWAL
mything.mydomain.com mydomain.com PENDING_AUTO_RENEWAL
You can perform a similar operation for ValidationEmails, I didn't include it in this example because that would have made too many properties to format cleanly on Stack Overflow. If you wanted to unroll the collection and convert it into a string, its calculated property would look something like this:
#{N='ValidationEmails';E={$_.DomainValidationOptions.ValidationEmails -join ','}}
Further Reading
AWS PowerShell Documentation - Get-ACMCertificateDetail
AWS SDK For .NET Documentation - Amazon.CertificateManager.Model.CertificateDetail
- There is an especially helpful note in here about RenewalSummary: "This field exists only when the certificate type is AMAZON_ISSUED."
Additional Note For Readers: I had to update to latest AWS PowerShell to be able to see RenewalSummary. If you can't see this property but expect that you should be able to, try updating your local AWS PowerShell version.

Does Get-WebApplication returns invalid objects?

Why do I don't get valid names, if I use Get-WebApplication in PowerShell like this:
Get-WebApplication | ForEach-Object { write-host $_.Name }
In the result set, the name properties are empty. Why?
Instead Get-WebApplication does return a structure like:
PS> Get-WebApplication
Name Application pool Protocols Physical Path
---- ---------------- --------- -------------
test default http C:\....
Assuming Get-WebApplication is https://technet.microsoft.com/en-us/library/ee790554.aspx.
Name column in the output from Get-WebApplication seems to behave a little like a calculated property. I was unable to find out exactly what the formula is behind it but by running
Get-WebApplication | select -ExpandProperty Path | select #{ n="Name";e={ $_.TrimStart('/') } }
you will get a similar looking result as to what you appear to be trying to extract.
This command selects and simplifies the Path property (essentially turns it into a string), then creates from it a calculated property that has the correct title and value.