Powershell array and changing members types.

Soldato
Joined
8 Mar 2005
Posts
3,850
Location
London, UK
Another silly pickle with Powershell and c#.

I have an array built from the output of a cmdlet which looks like this:
Code:
UserFullName     : usera
BrokeringTime    : 29/02/2020 06:47:11
ClientName       : clienta
DesktopGroupName : SHARED_PRD
SessionState     : Active
Uid              : 1234567
MachineName      : Servera
ENV              : UK

UserFullName     : usera
BrokeringTime    : 29/02/2020 06:57:11
ClientName       : clientb
DesktopGroupName : SHARED_PRD
SessionState     : Active
Uid              : 7654321
MachineName      : Serverb
ENV              : US
Member
Code:
Name             MemberType   Definition                                 
----             ----------   ----------                                 
Equals           Method       bool Equals(System.Object obj)             
GetHashCode      Method       int GetHashCode()                         
GetType          Method       type GetType()                             
ToString         Method       string ToString()                         
BrokeringTime    NoteProperty datetime BrokeringTime=29/02/2020 06:47:11
ClientName       NoteProperty string ClientName=clienta           
DesktopGroupName NoteProperty string DesktopGroupName=SHARED_PRD
ENV              NoteProperty System.String ENV=UK                       
MachineName      NoteProperty string MachineName=Servera 
SessionState     NoteProperty SessionState SessionState=Active           
Uid              NoteProperty long Uid=1234567
UserFullName     NoteProperty string UserFullName=usera
This array is generated via PowerShell and then parsed via this call and class (the offending columns are commented out).
Code:
 r => new MyClass
                        {
                            UserFullName = (string)r.Properties["UserFullName"].Value,
                            BrokeringTime = (DateTime)r.Properties["BrokeringTime"].Value,
                            ClientName = (string)r.Properties["ClientName"].Value,
                            DesktopGroupName = (string)r.Properties["DesktopGroupName"].Value,
                            //SessionState = (string)r.Properties["SessionState"].Value,
                            Uid = (Int64)r.Properties["Uid"].Value,
                            MachineName = (string)r.Properties["MachineName"].Value,
                            //ENV = (string)r.Properties["ENV"].Value,
                        }
                    );



internal class MyClass
    {
        public string UserFullName { get; set; }
        public DateTime BrokeringTime { get; set; }
        public string ClientName { get; set; }
        public string DesktopGroupName { get; set; }
        public string SessionState { get; set; }
        public Int64 Uid { get; set; }
        public string MachineName { get; set; }
        public string ENV { get; set; }
    }
It throws a wobbly as it is unable to parse System.String or SessionState (ENV and SessionState(?!)) as standard strings. I would imagine the easiest solution here would simply be to change the member types of the offending columns BUT I cannot seem to find an easy or obvious way to do this without losing the array structure. Even when converting the lot to an array string it then defines all columns as System.string.

Possibly backside about face but are you able to redefine object definitions within an array to String (as opposed to System.String).

TIA!
 
In the original command from PS, can't you force the array value to a string?

Code:
Get-SomeCommand | Select UserFullName, BrokeringTime, ClientName, DesktopGroupName, @{Name="SessionState";Expression={$_.SessionState.ToString()}}, Uid, MachineName, @{Name="ENV";Expression={$_.ENV.ToString()}}
 
Still classes ENV it as a system.string but it does alter the session column from sessionstate to system.string.

Code:
$a = Get-BrokerSession -BrokeringUserName user | Select-Object UserFullName, BrokeringTime, ClientName,DesktopGroupName, @{Name="SessionState";Expression={$_.SessionState.ToString()}}, uid, machinename,@{Name='ENV';Expression={'UK'.ToString()}}

UserFullName     : user
BrokeringTime    : 02/03/2020 07:01:39
ClientName       : localclient
DesktopGroupName : DesktopName
SessionState     : Active
Uid              : 1416007
MachineName      : Name
ENV              : UK


Name             MemberType   Definition
----             ----------   ----------
Equals           Method       bool Equals(System.Object obj)
GetHashCode      Method       int GetHashCode()
GetType          Method       type GetType()
ToString         Method       string ToString()
BrokeringTime    NoteProperty datetime BrokeringTime=02/03/2020 07:01:39
ClientName       NoteProperty string ClientName=localclient
DesktopGroupName NoteProperty string DesktopGroupName=DesktopName
ENV              NoteProperty System.String ENV=UK
MachineName      NoteProperty string MachineName=Name
SessionState     NoteProperty System.String SessionState=Active
Uid              NoteProperty long Uid=1416007
UserFullName     NoteProperty string UserFullName=user
 
Not really understanding what's happening here!
Think I might have a way around for you though by creating an intermediary custom object. There's probably a much easier way of doing this but here goes...

Creating a custom object the main object type is a system.string but the field definition is 'string fieldname=whatever' which your c code appears to like?
Code:
$Row = "" | Select ENV
$Row.ENV = "test string"
$Row | Get-member


   TypeName: Selected.System.String

Name        MemberType   Definition                  
----        ----------   ----------                  
Equals      Method       bool Equals(System.Object obj)
GetHashCode Method       int GetHashCode()            
GetType     Method       type GetType()              
ToString    Method       string ToString()            
ENV         NoteProperty string ENV=test string

So perhaps try:
Code:
$a = Get-BrokerSession -BrokeringUserName user | Select-Object UserFullName, BrokeringTime, ClientName, DesktopGroupName, SessionState, uid, machinename, ENV

$b = @()
ForEach ($Session In $a)
{
    $Row = "" | Select UserFullName, BrokeringTime, ClientName, DesktopGroupName, SessionState, uid, machinename, ENV

    $Row.UserFullName = $Session.UserFullName
    $Row.BrokeringTime = $Session.BrokeringTime
    $Row.ClientName = $Session.ClientName
    $Row.DesktopGroupName = $Session.DesktopGroupName
    $Row.SessionState = $Session.SessionState
    $Row.uid = $Session.uid
    $Row.machinename = $Session.machinename
    $Row.ENV = $Session.ENV

    $b += $Row
}

Then just pass b over to your c jobbie and see what happens?!

Don't have the original cmdlet so can't really test - it might just come over with the same type in which case... dunno!
 
I'm stumped; makes zero difference;
Code:
$a = Get-BrokerSession -BrokeringUserName $user  | Select-Object UserFullName, BrokeringTime, ClientName, DesktopGroupName, SessionState, uid, machinename, @{Name='ENV';Expression={'UK'.ToString()}}

$b = @()
ForEach ($Session In $a)
{
    $Row = "" | Select UserFullName, BrokeringTime, ClientName, DesktopGroupName, SessionState, uid, machinename, ENV

    $Row.UserFullName = $Session.UserFullName
    $Row.BrokeringTime = $Session.BrokeringTime
    $Row.ClientName = $Session.ClientName
    $Row.DesktopGroupName = $Session.DesktopGroupName
    $Row.SessionState = $Session.SessionState
    $Row.uid = $Session.uid
    $Row.machinename = $Session.machinename
    $Row.ENV = $Session.ENV

    $b += $Row
}


$b | get-member


   TypeName: Selected.System.String

Name             MemberType   Definition                                     
----             ----------   ----------                                     
Equals           Method       bool Equals(System.Object obj)                 
GetHashCode      Method       int GetHashCode()                               
GetType          Method       type GetType()                                 
ToString         Method       string ToString()                               
BrokeringTime    NoteProperty datetime BrokeringTime=04/03/2020 11:46:25     
ClientName       NoteProperty string ClientName=client
DesktopGroupName NoteProperty string DesktopGroupName=desktopname
ENV              NoteProperty System.String ENV=UK                           
machinename      NoteProperty string machinename=machinename      
SessionState     NoteProperty SessionState SessionState=Active               
uid              NoteProperty long uid=70887                                 
UserFullName     NoteProperty string UserFullName=user

Thanks for having a go!
 
I'm stumped; makes zero difference;
Code:
$a = Get-BrokerSession -BrokeringUserName $user  | Select-Object UserFullName, BrokeringTime, ClientName, DesktopGroupName, SessionState, uid, machinename, @{Name='ENV';Expression={'UK'.ToString()}}

$b = @()
ForEach ($Session In $a)
{
    $Row = "" | Select UserFullName, BrokeringTime, ClientName, DesktopGroupName, SessionState, uid, machinename, ENV

    $Row.UserFullName = $Session.UserFullName
    $Row.BrokeringTime = $Session.BrokeringTime
    $Row.ClientName = $Session.ClientName
    $Row.DesktopGroupName = $Session.DesktopGroupName
    $Row.SessionState = "$($Session.SessionState)"
    $Row.uid = $Session.uid
    $Row.machinename = $Session.machinename
    $Row.ENV = "$($Session.ENV)"

    $b += $Row
}


$b | get-member

Thanks for having a go!

Maybe try encapsulating the object and forcing inside a string?! Amended the two fields above
 
Dagnabbit; that did it! Thanks. Sheesh!

Ah cool! You should be able to do this a bit easier then:
Code:
$a = Get-BrokerSession -BrokeringUserName $user |
Select-Object UserFullName, BrokeringTime, ClientName, DesktopGroupName, @{Name='SessionState';Expression={"$($_.SessionState)"}}, uid, machinename, @{Name='ENV';Expression={"$($_.ENV)"}}

Switched env back to getting it from the cmdlet - if it's a custom field could just say:
@{Name='ENV';Expression={"UK"}} or
@{Name='ENV';Expression={"$(UK)"}} - although that shouldn't be any different!
 
Thanks again. I'll try the above and report back; I'm so flustered with it that I need a break! I have so many frustrations and questions I'm trying my best to limit to a question per every few weeks! (:
 
Back
Top Bottom