Author Posts

June 10, 2015 at 5:02 am

Hi,

I'm trying to learn the new-object command at the moment. scratching around on the internet I found this script. I'm trying to understand what the person is doing.
First line, all good. I get that bit.
But the rest is a bit confusing. That doesn't look like the right way to use the "foreach" command and the { } enclosing the new-object part is strange as its not passing anything on, like they wanted to create a hash table ?

$ip = ipconfig | Select-String "IPv4|Subnet|Gateway" | select-object -first 3
$ip | foreach { $ipo = New-Object psobject }
{$prop,$value = $_.ToString().Split(":") 
Add-member -InputObject $ipo noteproperty -Name $prop.Trim(". :") -Value $value.Trim()}

Must admit the psobject, psocustomobject, new-object and add-member i'm finding hard to get my head around. Any help would be much appreciated.

June 10, 2015 at 5:28 am

Hey there Graham,

Do you have a URL where the original code was posted? I'm having a little trouble with it and not sure if it's how the new site format is formatting the code.

Also, I did a blog post not too long ago on using PSCustomObject, which I like a lot more than the New-Object method better. But if you're stuck in v2 you'll need New-Object. Here's the post if you'd like to read up a bit.

PowerShell – Fun With PSCustomObjects

I'll see if I can find a better example of usage with New-Object. If not, I'll write something up for our KB. 🙂

June 10, 2015 at 6:09 am

Hi Will,

Great stuff, many thanks !

Here is the link, https://getpowershell.wordpress.com/2008/02/10/i-object-to-ipconfig/.

I'm trying to look at working new-object/pscustomobject, then pick them apart to get an understanding. Finding this part quite tricky.

June 10, 2015 at 6:33 am

I'll grab a few minutes at lunch and rework an example for using New-Object for you. Stay tuned. 🙂

June 10, 2015 at 9:15 am

Hey there Graham,

I whipped up a quick script using the same example directory as my blog post, but utilizing the New-Object PSObject method as opposed to the PSCustomObject method. I'll whip up a KB article on it a bit later, but at least you can see what's involved with the New-Object method by this example without the string manipulation in the online example you showed. Let me know if you need more clarification!

$Path = "c:\scripts"
$Directory = Get-Acl -Path $Path

ForEach ($Dir in $Directory.Access){

    $DirPermissions = New-Object -TypeName PSObject
    $DirPermissions | Add-Member -MemberType NoteProperty -Name Path -Value $Path
    $DirPermissions | Add-Member -MemberType NoteProperty -Name Owner -Value $Directory.Owner
    $DirPermissions | Add-Member -MemberType NoteProperty -Name Group -Value $Dir.IdentityReference
    $DirPermissions | Add-Member -MemberType NoteProperty -Name AccessType -Value $Dir.AccessControlType
    $DirPermissions | Add-Member -MemberType NoteProperty -Name Rights -Value $Dir.FileSystemRights

    $DirPermissions
}

June 10, 2015 at 9:32 am

Thanks.
What are the differences between psobject, pscustomobject and new-object ?
For some reason it's not quite sinking in and I'm not sure how to grasp it. Even the add-member is confusing. Done ok so far in my learning but this is a bit more tricky. If something is an object does that mean I get the methods, properties etc, which is the benefit ? Frustrating !

June 10, 2015 at 9:42 am

Other experts can feel free to chime in here, because I'm really bad at the programmatic side of PowerShell. 🙂 My explanation:

New-Object is a cmdlet that allows you to create a custom .NET or COM object. When using it to create a custom PSObject, you would declare that object like so:

New-Object -TypeName PSObject

And then add the members to your object using the Add-Member cmdlet.

PSCustomObject is a class that was added in PSv3 that allows you to essentially do the same thing, but using a hashtable instead of a separate line for each member you want to add.

The advantage to PSCustomObject is that it maintains the specific order that you create in your hashtable, whereas the New-Object PSObject method doesn't. PSCustomObject is also usually faster in enumerating your data. Really good discussion about it here:

Also, it's a lot less typing and easier to read.

http://stackoverflow.com/questions/14012773/difference-between-psobject-hashtable-and-pscustomobject

The disadvantage to PSCustomObject is that you can't use it on systems using PSv2. So you're stuck with New-Object if you're working on systems older than 2008 R2.

Long story short, PSCustomObject and PSObject at their roots are pretty much the same thing, it's just that leveraging PSCustomObject is more efficient.

June 10, 2015 at 9:53 am

Thank you will, most helpful. I've read your article on the link you supplied and that helped make a bit more sense. Think I need to keep practicing !

June 10, 2015 at 9:54 am

Go for it! PSCustomObject is one of my favorite PowerShell features to play with. That and string manipulation.

Have fun!

June 11, 2015 at 6:54 am

A nicer way to write that.

$Path = "c:\scripts"

$Directory = Get-Acl -Path $Path




$p = @{

path = $path
owner = $directory.owner
group = $dir.identityreference
accesstype = $dir.accesscontroltype
rights = $dir.filesystemrights

}



ForEach ($Dir in $Directory.Access){

   

New-Object psobject -Property $p

}

June 11, 2015 at 9:23 am

@Dan

Your properties need to be in the loop:

$Path = "c:\scripts"

$Directory = Get-Acl -Path $Path

ForEach ($Dir in $Directory.Access){
    $p = @{
        path = $path
        owner = $directory.owner
        group = $dir.identityreference
        accesstype = $dir.accesscontroltype
        rights = $dir.filesystemrights
    }

    New-Object psobject -Property $p
}

June 11, 2015 at 10:19 am

Typo, just run it twice:-)

June 11, 2015 at 12:39 pm

Cheers guys. Having a play myself. How can i combine two different commands into a PSCustomObject ?

$BIOS = get-ciminstance -Namespace ROOT\CIMV2 -ClassName Win32_BIOS 
$BIOS2 = get-ciminstance -Namespace ROOT\CIMV2 -ClassName Win32_ComputerSystem 


$BIOS | ForEach-Object {
[pscustomobject]@{
"BIOS Version" = $_.SMBIOSBIOSVersion.Trim("B0ET28WW ( )") 
$BIOS2 | Foreach-object {
"Model of Desktop" =  $_.Model
     } 
}
}

June 11, 2015 at 12:50 pm

OK, i'm playing and trying to get a grip on this, am i on the right lines ?

$BIOS = get-ciminstance -Namespace ROOT\CIMV2 -ClassName Win32_BIOS 
$BIOS2 = get-ciminstance -Namespace ROOT\CIMV2 -ClassName Win32_ComputerSystem 

[pscustomobject]@{
"BIOS Version" = $bios.SMBIOSBIOSVersion.Trim("B0ET28WW ( )") 
"Model of desktop" = $BIOS2.Model
     } 

June 11, 2015 at 12:51 pm

I was able to execute it on my system. Well done! Keep going! 🙂