Powershell - Retain the text of all Enum properties with ConvertTo-Json












6















For "Get-Msoldomain" powershell command-let I get the below output (lets call it Output#1) where Name, Status and Authentication are the property names and below are their respective values.



Name                    Status   Authentication

myemail.onmicrosoft.com Verified Managed


When I use the command with "ConvertTo-Json" like below



GetMsolDomain |ConvertTo-Json


I get the below output (lets call it Output#2) in Json Format.



{
"ExtensionData": {

},
"Authentication": 0,
"Capabilities": 5,
"IsDefault": true,
"IsInitial": true,
"Name": "myemail.onmicrosoft.com",
"RootDomain": null,
"Status": 1,
"VerificationMethod": 1
}


However, the problem is, that if you notice the Status property in both the outputs, it's different. Same happens for VerificationMethod property. Without using the ConvertTo-JSon Powershell gives the Text, and with using ConvertTo-Json it gives the integer.



When I give the below command



get-msoldomain |Select-object @{Name='Status';Expression={"$($_.Status)"}}|ConvertTo-json


I get the output as



{
"Status": "Verified"
}


However, I want something so that I don't have to specify any specific property name for it to be converted , the way I am specifying above as



Select-object @{Name='Status';Expression={"$($_.Status)"}}


This line is transforming only the Status Property and not the VerificationMethod property because that is what I am providing as input .



Question: Is there something generic that I can give to the "ConvertTo-Json" commandlet, so that It returns ALL the Enum properties as Texts and not Integers, without explicitly naming them, so that I get something like below as the output:



{
"ExtensionData": {

},
"Authentication": 0,
"Capabilities": 5,
"IsDefault": true,
"IsInitial": true,
"Name": "myemail.onmicrosoft.com",
"RootDomain": null,
"Status": "Verified",
"VerificationMethod": "DnsRecord"
}









share|improve this question



























    6















    For "Get-Msoldomain" powershell command-let I get the below output (lets call it Output#1) where Name, Status and Authentication are the property names and below are their respective values.



    Name                    Status   Authentication

    myemail.onmicrosoft.com Verified Managed


    When I use the command with "ConvertTo-Json" like below



    GetMsolDomain |ConvertTo-Json


    I get the below output (lets call it Output#2) in Json Format.



    {
    "ExtensionData": {

    },
    "Authentication": 0,
    "Capabilities": 5,
    "IsDefault": true,
    "IsInitial": true,
    "Name": "myemail.onmicrosoft.com",
    "RootDomain": null,
    "Status": 1,
    "VerificationMethod": 1
    }


    However, the problem is, that if you notice the Status property in both the outputs, it's different. Same happens for VerificationMethod property. Without using the ConvertTo-JSon Powershell gives the Text, and with using ConvertTo-Json it gives the integer.



    When I give the below command



    get-msoldomain |Select-object @{Name='Status';Expression={"$($_.Status)"}}|ConvertTo-json


    I get the output as



    {
    "Status": "Verified"
    }


    However, I want something so that I don't have to specify any specific property name for it to be converted , the way I am specifying above as



    Select-object @{Name='Status';Expression={"$($_.Status)"}}


    This line is transforming only the Status Property and not the VerificationMethod property because that is what I am providing as input .



    Question: Is there something generic that I can give to the "ConvertTo-Json" commandlet, so that It returns ALL the Enum properties as Texts and not Integers, without explicitly naming them, so that I get something like below as the output:



    {
    "ExtensionData": {

    },
    "Authentication": 0,
    "Capabilities": 5,
    "IsDefault": true,
    "IsInitial": true,
    "Name": "myemail.onmicrosoft.com",
    "RootDomain": null,
    "Status": "Verified",
    "VerificationMethod": "DnsRecord"
    }









    share|improve this question

























      6












      6








      6


      1






      For "Get-Msoldomain" powershell command-let I get the below output (lets call it Output#1) where Name, Status and Authentication are the property names and below are their respective values.



      Name                    Status   Authentication

      myemail.onmicrosoft.com Verified Managed


      When I use the command with "ConvertTo-Json" like below



      GetMsolDomain |ConvertTo-Json


      I get the below output (lets call it Output#2) in Json Format.



      {
      "ExtensionData": {

      },
      "Authentication": 0,
      "Capabilities": 5,
      "IsDefault": true,
      "IsInitial": true,
      "Name": "myemail.onmicrosoft.com",
      "RootDomain": null,
      "Status": 1,
      "VerificationMethod": 1
      }


      However, the problem is, that if you notice the Status property in both the outputs, it's different. Same happens for VerificationMethod property. Without using the ConvertTo-JSon Powershell gives the Text, and with using ConvertTo-Json it gives the integer.



      When I give the below command



      get-msoldomain |Select-object @{Name='Status';Expression={"$($_.Status)"}}|ConvertTo-json


      I get the output as



      {
      "Status": "Verified"
      }


      However, I want something so that I don't have to specify any specific property name for it to be converted , the way I am specifying above as



      Select-object @{Name='Status';Expression={"$($_.Status)"}}


      This line is transforming only the Status Property and not the VerificationMethod property because that is what I am providing as input .



      Question: Is there something generic that I can give to the "ConvertTo-Json" commandlet, so that It returns ALL the Enum properties as Texts and not Integers, without explicitly naming them, so that I get something like below as the output:



      {
      "ExtensionData": {

      },
      "Authentication": 0,
      "Capabilities": 5,
      "IsDefault": true,
      "IsInitial": true,
      "Name": "myemail.onmicrosoft.com",
      "RootDomain": null,
      "Status": "Verified",
      "VerificationMethod": "DnsRecord"
      }









      share|improve this question














      For "Get-Msoldomain" powershell command-let I get the below output (lets call it Output#1) where Name, Status and Authentication are the property names and below are their respective values.



      Name                    Status   Authentication

      myemail.onmicrosoft.com Verified Managed


      When I use the command with "ConvertTo-Json" like below



      GetMsolDomain |ConvertTo-Json


      I get the below output (lets call it Output#2) in Json Format.



      {
      "ExtensionData": {

      },
      "Authentication": 0,
      "Capabilities": 5,
      "IsDefault": true,
      "IsInitial": true,
      "Name": "myemail.onmicrosoft.com",
      "RootDomain": null,
      "Status": 1,
      "VerificationMethod": 1
      }


      However, the problem is, that if you notice the Status property in both the outputs, it's different. Same happens for VerificationMethod property. Without using the ConvertTo-JSon Powershell gives the Text, and with using ConvertTo-Json it gives the integer.



      When I give the below command



      get-msoldomain |Select-object @{Name='Status';Expression={"$($_.Status)"}}|ConvertTo-json


      I get the output as



      {
      "Status": "Verified"
      }


      However, I want something so that I don't have to specify any specific property name for it to be converted , the way I am specifying above as



      Select-object @{Name='Status';Expression={"$($_.Status)"}}


      This line is transforming only the Status Property and not the VerificationMethod property because that is what I am providing as input .



      Question: Is there something generic that I can give to the "ConvertTo-Json" commandlet, so that It returns ALL the Enum properties as Texts and not Integers, without explicitly naming them, so that I get something like below as the output:



      {
      "ExtensionData": {

      },
      "Authentication": 0,
      "Capabilities": 5,
      "IsDefault": true,
      "IsInitial": true,
      "Name": "myemail.onmicrosoft.com",
      "RootDomain": null,
      "Status": "Verified",
      "VerificationMethod": "DnsRecord"
      }






      json powershell enums






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jun 12 '17 at 8:09









      puneetpuneet

      128113




      128113
























          2 Answers
          2






          active

          oldest

          votes


















          6














          Well, if you don't mind to take a little trip :) you can convert it to CSV which will force the string output, then re-convert it back from CSV to PS Object, then finally back to Json.



          Like this:



          Get-MsolDomain | ConvertTo-Csv | ConvertFrom-Csv | ConvertTo-Json



          • If you need to keep the original Types instead of converting it all to string see mklement0 helpful answer...






          share|improve this answer


























          • A simple and pragmatic solution, but (efficiency aside) it comes with a big caveat: All property values are invariably converted to strings, which is generally undesirable.

            – mklement0
            Jan 3 at 14:45



















          2














          PowerShell Core offers a simple solution via ConvertTo-Json's -EnumsAsStrings switch.



          GetMsolDomain | ConvertTo-Json -EnumsAsStrings  # PS *Core* only




          Unfortunately, this switch isn't supported in Windows PowerShell.



          Avshalom's answer provides a quick workaround that comes with a big caveat, however: All property values are invariably converted to strings in the process, which is generally undesirable.



          Here's a more generic workaround based on a filter function that recursively introspects the input objects and outputs ordered hashtables that reflect the input properties with enumeration values converted to strings and all other values passed through, which you can then pass to ConvertTo-Json:



          Filter ConvertTo-EnumsAsStrings ([int] $Depth = 2, [int] $CurrDepth = 0) {
          if ($_ -is [enum]) { # enum value -> convert to symbolic name as string
          $_.ToString()
          } elseif ($null -eq $_ -or $_.GetType().IsPrimitive -or $_ -is [string] -or $_ -is [decimal] -or $_ -is [datetime] -or $_ -is [datetimeoffset]) {
          $_
          } elseif ($_ -is [Collections.IEnumerable]) {
          , ($_ | ConvertTo-EnumsAsStrings -Depth $Depth -CurrDepth ($CurrDepth+1))
          } else { # non-primitive type -> recurse on properties
          if ($CurrDepth -gt $Depth) { # depth exceeded -> return .ToString() representation
          "$_"
          } else {
          $oht = [ordered] @{}
          foreach ($prop in $_.psobject.properties) {
          if ($prop.Value -is [Collections.IEnumerable] -and -not $prop.Value -is [string]) {
          $oht[$prop.Name] = @($prop.Value | ConvertTo-EnumsAsStrings -Depth $Depth -CurrDepth ($CurrDepth+1))
          } else {
          $oht[$prop.Name] = $prop.Value | ConvertTo-EnumsAsStrings -Depth $Depth -CurrDepth ($CurrDepth+1)
          }
          }
          $oht
          }
          }
          }


          Caveat: As with ConvertTo-Json, the recursion depth (-Depth) is limited to 2 by default, to prevent infinite recursion / excessively large output (as you would get with types such as [System.IO.FileInfo] via Get-ChildItem, for instance). Similarly, values that exceed the implied or specified depth are represented by their .ToString() value. Use -Depth explicitly to control the recursion depth.



          Example call:



          PS> [pscustomobject] @{ p1 = [platformId]::Unix; p2 = 'hi'; p3 = 1; p4 = $true } | 
          ConvertTo-EnumsAsStrings -Depth 2 |
          ConvertTo-Json

          {
          "p1": "Unix", # Enum value [platformId]::Unix represented as string.
          "p2": "hi", # Other types of values were left as-is.
          "p3": 1,
          "p4": true
          }


          Note: -Depth 2 isn't necessary here, given that 2 is the default value (and given that the input has depth 0), but it is shown here as a reminder that you may want to control it explicitly.






          share|improve this answer





















          • 1





            This is a far better answer than the accepted answer

            – Rob McFeely
            Mar 25 at 18:07












          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f44494409%2fpowershell-retain-the-text-of-all-enum-properties-with-convertto-json%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          6














          Well, if you don't mind to take a little trip :) you can convert it to CSV which will force the string output, then re-convert it back from CSV to PS Object, then finally back to Json.



          Like this:



          Get-MsolDomain | ConvertTo-Csv | ConvertFrom-Csv | ConvertTo-Json



          • If you need to keep the original Types instead of converting it all to string see mklement0 helpful answer...






          share|improve this answer


























          • A simple and pragmatic solution, but (efficiency aside) it comes with a big caveat: All property values are invariably converted to strings, which is generally undesirable.

            – mklement0
            Jan 3 at 14:45
















          6














          Well, if you don't mind to take a little trip :) you can convert it to CSV which will force the string output, then re-convert it back from CSV to PS Object, then finally back to Json.



          Like this:



          Get-MsolDomain | ConvertTo-Csv | ConvertFrom-Csv | ConvertTo-Json



          • If you need to keep the original Types instead of converting it all to string see mklement0 helpful answer...






          share|improve this answer


























          • A simple and pragmatic solution, but (efficiency aside) it comes with a big caveat: All property values are invariably converted to strings, which is generally undesirable.

            – mklement0
            Jan 3 at 14:45














          6












          6








          6







          Well, if you don't mind to take a little trip :) you can convert it to CSV which will force the string output, then re-convert it back from CSV to PS Object, then finally back to Json.



          Like this:



          Get-MsolDomain | ConvertTo-Csv | ConvertFrom-Csv | ConvertTo-Json



          • If you need to keep the original Types instead of converting it all to string see mklement0 helpful answer...






          share|improve this answer















          Well, if you don't mind to take a little trip :) you can convert it to CSV which will force the string output, then re-convert it back from CSV to PS Object, then finally back to Json.



          Like this:



          Get-MsolDomain | ConvertTo-Csv | ConvertFrom-Csv | ConvertTo-Json



          • If you need to keep the original Types instead of converting it all to string see mklement0 helpful answer...







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 3 at 17:50

























          answered Jun 12 '17 at 8:47









          AvshalomAvshalom

          5,46111633




          5,46111633













          • A simple and pragmatic solution, but (efficiency aside) it comes with a big caveat: All property values are invariably converted to strings, which is generally undesirable.

            – mklement0
            Jan 3 at 14:45



















          • A simple and pragmatic solution, but (efficiency aside) it comes with a big caveat: All property values are invariably converted to strings, which is generally undesirable.

            – mklement0
            Jan 3 at 14:45

















          A simple and pragmatic solution, but (efficiency aside) it comes with a big caveat: All property values are invariably converted to strings, which is generally undesirable.

          – mklement0
          Jan 3 at 14:45





          A simple and pragmatic solution, but (efficiency aside) it comes with a big caveat: All property values are invariably converted to strings, which is generally undesirable.

          – mklement0
          Jan 3 at 14:45













          2














          PowerShell Core offers a simple solution via ConvertTo-Json's -EnumsAsStrings switch.



          GetMsolDomain | ConvertTo-Json -EnumsAsStrings  # PS *Core* only




          Unfortunately, this switch isn't supported in Windows PowerShell.



          Avshalom's answer provides a quick workaround that comes with a big caveat, however: All property values are invariably converted to strings in the process, which is generally undesirable.



          Here's a more generic workaround based on a filter function that recursively introspects the input objects and outputs ordered hashtables that reflect the input properties with enumeration values converted to strings and all other values passed through, which you can then pass to ConvertTo-Json:



          Filter ConvertTo-EnumsAsStrings ([int] $Depth = 2, [int] $CurrDepth = 0) {
          if ($_ -is [enum]) { # enum value -> convert to symbolic name as string
          $_.ToString()
          } elseif ($null -eq $_ -or $_.GetType().IsPrimitive -or $_ -is [string] -or $_ -is [decimal] -or $_ -is [datetime] -or $_ -is [datetimeoffset]) {
          $_
          } elseif ($_ -is [Collections.IEnumerable]) {
          , ($_ | ConvertTo-EnumsAsStrings -Depth $Depth -CurrDepth ($CurrDepth+1))
          } else { # non-primitive type -> recurse on properties
          if ($CurrDepth -gt $Depth) { # depth exceeded -> return .ToString() representation
          "$_"
          } else {
          $oht = [ordered] @{}
          foreach ($prop in $_.psobject.properties) {
          if ($prop.Value -is [Collections.IEnumerable] -and -not $prop.Value -is [string]) {
          $oht[$prop.Name] = @($prop.Value | ConvertTo-EnumsAsStrings -Depth $Depth -CurrDepth ($CurrDepth+1))
          } else {
          $oht[$prop.Name] = $prop.Value | ConvertTo-EnumsAsStrings -Depth $Depth -CurrDepth ($CurrDepth+1)
          }
          }
          $oht
          }
          }
          }


          Caveat: As with ConvertTo-Json, the recursion depth (-Depth) is limited to 2 by default, to prevent infinite recursion / excessively large output (as you would get with types such as [System.IO.FileInfo] via Get-ChildItem, for instance). Similarly, values that exceed the implied or specified depth are represented by their .ToString() value. Use -Depth explicitly to control the recursion depth.



          Example call:



          PS> [pscustomobject] @{ p1 = [platformId]::Unix; p2 = 'hi'; p3 = 1; p4 = $true } | 
          ConvertTo-EnumsAsStrings -Depth 2 |
          ConvertTo-Json

          {
          "p1": "Unix", # Enum value [platformId]::Unix represented as string.
          "p2": "hi", # Other types of values were left as-is.
          "p3": 1,
          "p4": true
          }


          Note: -Depth 2 isn't necessary here, given that 2 is the default value (and given that the input has depth 0), but it is shown here as a reminder that you may want to control it explicitly.






          share|improve this answer





















          • 1





            This is a far better answer than the accepted answer

            – Rob McFeely
            Mar 25 at 18:07
















          2














          PowerShell Core offers a simple solution via ConvertTo-Json's -EnumsAsStrings switch.



          GetMsolDomain | ConvertTo-Json -EnumsAsStrings  # PS *Core* only




          Unfortunately, this switch isn't supported in Windows PowerShell.



          Avshalom's answer provides a quick workaround that comes with a big caveat, however: All property values are invariably converted to strings in the process, which is generally undesirable.



          Here's a more generic workaround based on a filter function that recursively introspects the input objects and outputs ordered hashtables that reflect the input properties with enumeration values converted to strings and all other values passed through, which you can then pass to ConvertTo-Json:



          Filter ConvertTo-EnumsAsStrings ([int] $Depth = 2, [int] $CurrDepth = 0) {
          if ($_ -is [enum]) { # enum value -> convert to symbolic name as string
          $_.ToString()
          } elseif ($null -eq $_ -or $_.GetType().IsPrimitive -or $_ -is [string] -or $_ -is [decimal] -or $_ -is [datetime] -or $_ -is [datetimeoffset]) {
          $_
          } elseif ($_ -is [Collections.IEnumerable]) {
          , ($_ | ConvertTo-EnumsAsStrings -Depth $Depth -CurrDepth ($CurrDepth+1))
          } else { # non-primitive type -> recurse on properties
          if ($CurrDepth -gt $Depth) { # depth exceeded -> return .ToString() representation
          "$_"
          } else {
          $oht = [ordered] @{}
          foreach ($prop in $_.psobject.properties) {
          if ($prop.Value -is [Collections.IEnumerable] -and -not $prop.Value -is [string]) {
          $oht[$prop.Name] = @($prop.Value | ConvertTo-EnumsAsStrings -Depth $Depth -CurrDepth ($CurrDepth+1))
          } else {
          $oht[$prop.Name] = $prop.Value | ConvertTo-EnumsAsStrings -Depth $Depth -CurrDepth ($CurrDepth+1)
          }
          }
          $oht
          }
          }
          }


          Caveat: As with ConvertTo-Json, the recursion depth (-Depth) is limited to 2 by default, to prevent infinite recursion / excessively large output (as you would get with types such as [System.IO.FileInfo] via Get-ChildItem, for instance). Similarly, values that exceed the implied or specified depth are represented by their .ToString() value. Use -Depth explicitly to control the recursion depth.



          Example call:



          PS> [pscustomobject] @{ p1 = [platformId]::Unix; p2 = 'hi'; p3 = 1; p4 = $true } | 
          ConvertTo-EnumsAsStrings -Depth 2 |
          ConvertTo-Json

          {
          "p1": "Unix", # Enum value [platformId]::Unix represented as string.
          "p2": "hi", # Other types of values were left as-is.
          "p3": 1,
          "p4": true
          }


          Note: -Depth 2 isn't necessary here, given that 2 is the default value (and given that the input has depth 0), but it is shown here as a reminder that you may want to control it explicitly.






          share|improve this answer





















          • 1





            This is a far better answer than the accepted answer

            – Rob McFeely
            Mar 25 at 18:07














          2












          2








          2







          PowerShell Core offers a simple solution via ConvertTo-Json's -EnumsAsStrings switch.



          GetMsolDomain | ConvertTo-Json -EnumsAsStrings  # PS *Core* only




          Unfortunately, this switch isn't supported in Windows PowerShell.



          Avshalom's answer provides a quick workaround that comes with a big caveat, however: All property values are invariably converted to strings in the process, which is generally undesirable.



          Here's a more generic workaround based on a filter function that recursively introspects the input objects and outputs ordered hashtables that reflect the input properties with enumeration values converted to strings and all other values passed through, which you can then pass to ConvertTo-Json:



          Filter ConvertTo-EnumsAsStrings ([int] $Depth = 2, [int] $CurrDepth = 0) {
          if ($_ -is [enum]) { # enum value -> convert to symbolic name as string
          $_.ToString()
          } elseif ($null -eq $_ -or $_.GetType().IsPrimitive -or $_ -is [string] -or $_ -is [decimal] -or $_ -is [datetime] -or $_ -is [datetimeoffset]) {
          $_
          } elseif ($_ -is [Collections.IEnumerable]) {
          , ($_ | ConvertTo-EnumsAsStrings -Depth $Depth -CurrDepth ($CurrDepth+1))
          } else { # non-primitive type -> recurse on properties
          if ($CurrDepth -gt $Depth) { # depth exceeded -> return .ToString() representation
          "$_"
          } else {
          $oht = [ordered] @{}
          foreach ($prop in $_.psobject.properties) {
          if ($prop.Value -is [Collections.IEnumerable] -and -not $prop.Value -is [string]) {
          $oht[$prop.Name] = @($prop.Value | ConvertTo-EnumsAsStrings -Depth $Depth -CurrDepth ($CurrDepth+1))
          } else {
          $oht[$prop.Name] = $prop.Value | ConvertTo-EnumsAsStrings -Depth $Depth -CurrDepth ($CurrDepth+1)
          }
          }
          $oht
          }
          }
          }


          Caveat: As with ConvertTo-Json, the recursion depth (-Depth) is limited to 2 by default, to prevent infinite recursion / excessively large output (as you would get with types such as [System.IO.FileInfo] via Get-ChildItem, for instance). Similarly, values that exceed the implied or specified depth are represented by their .ToString() value. Use -Depth explicitly to control the recursion depth.



          Example call:



          PS> [pscustomobject] @{ p1 = [platformId]::Unix; p2 = 'hi'; p3 = 1; p4 = $true } | 
          ConvertTo-EnumsAsStrings -Depth 2 |
          ConvertTo-Json

          {
          "p1": "Unix", # Enum value [platformId]::Unix represented as string.
          "p2": "hi", # Other types of values were left as-is.
          "p3": 1,
          "p4": true
          }


          Note: -Depth 2 isn't necessary here, given that 2 is the default value (and given that the input has depth 0), but it is shown here as a reminder that you may want to control it explicitly.






          share|improve this answer















          PowerShell Core offers a simple solution via ConvertTo-Json's -EnumsAsStrings switch.



          GetMsolDomain | ConvertTo-Json -EnumsAsStrings  # PS *Core* only




          Unfortunately, this switch isn't supported in Windows PowerShell.



          Avshalom's answer provides a quick workaround that comes with a big caveat, however: All property values are invariably converted to strings in the process, which is generally undesirable.



          Here's a more generic workaround based on a filter function that recursively introspects the input objects and outputs ordered hashtables that reflect the input properties with enumeration values converted to strings and all other values passed through, which you can then pass to ConvertTo-Json:



          Filter ConvertTo-EnumsAsStrings ([int] $Depth = 2, [int] $CurrDepth = 0) {
          if ($_ -is [enum]) { # enum value -> convert to symbolic name as string
          $_.ToString()
          } elseif ($null -eq $_ -or $_.GetType().IsPrimitive -or $_ -is [string] -or $_ -is [decimal] -or $_ -is [datetime] -or $_ -is [datetimeoffset]) {
          $_
          } elseif ($_ -is [Collections.IEnumerable]) {
          , ($_ | ConvertTo-EnumsAsStrings -Depth $Depth -CurrDepth ($CurrDepth+1))
          } else { # non-primitive type -> recurse on properties
          if ($CurrDepth -gt $Depth) { # depth exceeded -> return .ToString() representation
          "$_"
          } else {
          $oht = [ordered] @{}
          foreach ($prop in $_.psobject.properties) {
          if ($prop.Value -is [Collections.IEnumerable] -and -not $prop.Value -is [string]) {
          $oht[$prop.Name] = @($prop.Value | ConvertTo-EnumsAsStrings -Depth $Depth -CurrDepth ($CurrDepth+1))
          } else {
          $oht[$prop.Name] = $prop.Value | ConvertTo-EnumsAsStrings -Depth $Depth -CurrDepth ($CurrDepth+1)
          }
          }
          $oht
          }
          }
          }


          Caveat: As with ConvertTo-Json, the recursion depth (-Depth) is limited to 2 by default, to prevent infinite recursion / excessively large output (as you would get with types such as [System.IO.FileInfo] via Get-ChildItem, for instance). Similarly, values that exceed the implied or specified depth are represented by their .ToString() value. Use -Depth explicitly to control the recursion depth.



          Example call:



          PS> [pscustomobject] @{ p1 = [platformId]::Unix; p2 = 'hi'; p3 = 1; p4 = $true } | 
          ConvertTo-EnumsAsStrings -Depth 2 |
          ConvertTo-Json

          {
          "p1": "Unix", # Enum value [platformId]::Unix represented as string.
          "p2": "hi", # Other types of values were left as-is.
          "p3": 1,
          "p4": true
          }


          Note: -Depth 2 isn't necessary here, given that 2 is the default value (and given that the input has depth 0), but it is shown here as a reminder that you may want to control it explicitly.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 3 at 15:51

























          answered Jan 3 at 14:40









          mklement0mklement0

          137k22255293




          137k22255293








          • 1





            This is a far better answer than the accepted answer

            – Rob McFeely
            Mar 25 at 18:07














          • 1





            This is a far better answer than the accepted answer

            – Rob McFeely
            Mar 25 at 18:07








          1




          1





          This is a far better answer than the accepted answer

          – Rob McFeely
          Mar 25 at 18:07





          This is a far better answer than the accepted answer

          – Rob McFeely
          Mar 25 at 18:07


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f44494409%2fpowershell-retain-the-text-of-all-enum-properties-with-convertto-json%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Angular Downloading a file using contenturl with Basic Authentication

          Olmecas

          Can't read property showImagePicker of undefined in react native iOS