Properties not exporting to CSV - only headings?

Good Morning All,

I cannot see a reason for my properties not exporting to CSV, please could you take a look at my code and help me out:

[pre]
Add-PSSnapin Quest.ActiveRoles.ADManagement
Function Get-HomeDrive () {
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline = $True, Mandatory = $True)]
[Alias(‘User’, ‘Name’, ‘Email’, ‘Identity’)]
[String[]] $UserPrincipalName
)
BEGIN {}
PROCESS {
foreach ($User in $UserPrincipalName) {

        Get-QADUser -UserPrincipalName $User -IncludedProperties HomeDrive, homeDirectory | Select-Object UserPrincipalName, homeDirectory, HomeDrive

        $object = [pscustomobject]@{
            'UserPrincipalName' = $User.UserPrincipalName;
            'HomeDrive'         = $User.HomeDrive;
            'HomeDirectory'     = $User.homeDirectory
        
        }
        $object
        
    }
}

}
[/pre]

Add-PSSnapin Quest.ActiveRoles.ADManagement
Function Get-HomeDrive () {
    [CmdletBinding()]
    Param(
        [Parameter(ValueFromPipeline = $True, Mandatory = $True)]
        [Alias('User', 'Name', 'Email')]
        [String[]] $UserPrincipalName
    )
    PROCESS {
        $object = foreach ($User in $UserPrincipalName) {
            Get-QADUser-UserPrincipalName $User -IncludedProperties HomeDrive, homeDirectory |Select-Object UserPrincipalName, homeDirectory, HomeDrive
            [pscustomobject]@{
                'UserPrincipalName'= $User.UserPrincipalName;
                'HomeDrive'= $User.HomeDrive;
                'HomeDirectory'= $User.homeDirectory
            }
        }
        $object | Export-Csv -Path $PSScriptRoot\Users.csv -Append -NoTypeInformation
    }
}

This should work actually.
Is there a special reason why you use the old and pretty much obsolete Quest cmdlets instead of the AD cmdlets from Microsoft? And is there a special reason why you don’t indent your code accordingly? That would make it easier to read and to understand and to debug. :wink:

Hi Olaf,

Unfortunately I have to use the Quest Cmdlets as dictated by my boss because it logs who has touched AD objects with ActiveRoles Server. Apologies about the code indentation - it is actually indented properly (I use VS Code which formats automatically) but for some reason when I put the code between the pre tags it does not format it right.

I thought it should work too but for some reason it isn’t.

Yes, you’re overwriting $object each time in the loop with one new object, instead of accumulating them.

[quote quote=137015]Yes, you’re overwriting $object each time in the loop with one new object, instead of accumulating them.

[/quote]

I thought an ‘-append’ in the export-csv command would get around this?

I set a variable for the ‘Get-QADUser’ line and this seemed to have solved the problem - anyone know why please?

This is all about where you are exporting to the csv file.

[pre]
PROCESS {
$object = foreach ($User in $UserPrincipalName) {
Get-QADUser-UserPrincipalName $User -IncludedProperties HomeDrive, homeDirectory |Select-Object UserPrincipalName, homeDirectory, HomeDrive
[pscustomobject]@{
‘UserPrincipalName’= $User.UserPrincipalName;
‘HomeDrive’= $User.HomeDrive;
‘HomeDirectory’= $User.homeDirectory
}
$object | Export-Csv -Path $PSScriptRoot\Users.csv -Append -NoTypeInformation
}

}

[/pre]
every time you loop through the the foreach in your original example, you over-write $object.
you don’t actually do the export-csv until after you have completed iterating through the for-each loop.
See above, I’v you put your export line up one level so it sits inside of the foreach loop, so you will actually export the contents of $object each time you enumerate a user id.

Now an unexpected consequence of your code will be if you pass in an invalid user id.
You will have very unexpected results if that occurs.

[quote quote=137066]This is all about where you are exporting to the csv file.

PowerShell
14 lines
<textarea class="ace_text-input" autocorrect="off" autocapitalize="off" spellcheck="false" style="opacity: 0; height: 18px; width: 6.6px; left: 51px; top: 0px;" wrap="off"></textarea>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
PROCESS {
$object = foreach ($User in $UserPrincipalName) {
Get-QADUser-UserPrincipalName $User -IncludedProperties HomeDrive, homeDirectory |Select-Object UserPrincipalName, homeDirectory, HomeDrive
[pscustomobject]@{
'UserPrincipalName'= $User.UserPrincipalName;
'HomeDrive'= $User.HomeDrive;
'HomeDirectory'= $User.homeDirectory
}
$object | Export-Csv -Path $PSScriptRoot\Users.csv -Append -NoTypeInformation
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
every time you loop through the the foreach in your original example, you over-write $object.

you don’t actually do the export-csv until after you have completed iterating through the for-each loop.

See above, I’v you put your export line up one level so it sits inside of the foreach loop, so you will actually export the contents of $object each time you enumerate a user id.

Now an unexpected consequence of your code will be if you pass in an invalid user id.

You will have very unexpected results if that occurs.[/quote]

Thanks very much for your reply, is there a better way I can do this to avoid the unexpected behaviour if an invalid name is passed?

Another simplified form will be

Add-PSSnapin Quest.ActiveRoles.ADManagement
Function Get-HomeDrive () {
    [CmdletBinding()]
    Param(
        [Parameter(ValueFromPipeline = $True, Mandatory = $True)]
        [Alias('User', 'Name', 'Email')]
        [String[]] $UserPrincipalName
    )
    Process {
        [Array]$Object += foreach ($User in $UserPrincipalName) {
            try{
                Get-QADUser -UserPrincipalName $User -IncludedProperties HomeDrive, homeDirectory -ErrorAction Stop
            }
            catch{
                  #catch the unknown user error here
            }
        }        
    }
    End{
        $Object | Select-Object -Property UserPrincipalName, homeDirectory, HomeDrive | Export-Csv -Path $PSScriptRoot\Users.csv -NoTypeInformation
   }

Use try catch to handle the expected unkown user error.

[quote quote=137133]Another simplified form will be

PowerShell
22 lines
<textarea class="ace_text-input" style="opacity: 0; height: 18px; width: 7px; left: 51px; top: 0px;" spellcheck="false" wrap="off"></textarea>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Add-PSSnapin Quest.ActiveRoles.ADManagement
Function Get-HomeDrive () {
[CmdletBinding()]
Param(
[Parameter(ValueFromPipeline = $True, Mandatory = $True)]
[Alias('User', 'Name', 'Email')]
[String[]] $UserPrincipalName
)
PROCESS {
[Array]$Object += foreach ($User in $UserPrincipalName) {
try{
Get-QADUser -UserPrincipalName $User -IncludedProperties HomeDrive, homeDirectory -ErrorAction Stop
}
catch{
#catch the unknown user error here
}
}
}
End{
$Object | Select-Object -Property UserPrincipalName, homeDirectory, HomeDrive | Export-Csv -Path $PSScriptRoot\Users.csv -NoTypeInformation
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Use try catch to handle the expected unkown user error.

[/quote]

Thanks very much kvprasoon (It would be good to have a Thanks button on this forum).

It was there before, but removed recently !