Explore Your [Environment]

Explore Your [Environment]

  • Comments 18

This topic is a little long but I strongly encourage you to walk through it and master the techniques it illustrates.  I can assure you that you'll will use them a couple thousand times in the next couple of years.

.Net provides a wonderful class called System.Environment that tells you all about your environment.  It is well worth taking a few minutes to stop what you are doing and explore this class so that you understand its capabilities.  That way when a relevant issue comes up, you'll know that there is very simple way to get the answer. 

First thing to remember is that they way you specify a type in PowerShell is with square brackets:

PS> [System.Environment]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    Environment                              System.Object

 

The next thing to remember is that PowerShell allows you to drop the "SYSTEM" from types:

PS> [System.Diagnostics.Process]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    Process                                  System.ComponentModel.Component

PS> [Diagnostics.Process]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    Process                                  System.ComponentModel.Component

PS> [Environment]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    Environment                              System.Object

 

The next thing to remember is that types can have STATIC properties and methods.  What are a "static properties and methods"?  Most properties are methods that you deal with are OBJECT properties and methods which is to say that they are the "properties of THAT object" or the "methods that can be invoked on THAT object".  Static properties and methods do not require an object to be invoked.  There are lots of reasons why programmers use statics but the thing you need to know is that it is well worth exploring static properties and methods because they often contain gems of functionality.  Not all types have statics in fact most don't but those that do are often super useful so it is worth the explore.

So how do you explore?  Well with PowerShell of course.  Remember that PowerShell is designed to allow you to explore the system.  We want to to cultivate a strong sense of curiosity about your system and want to make it easy and safe (where possible) for you to go splunking around.  So the tool to explore Statics is Get-Member.   Here is what you need to know:

1) Get-Member has a -STATIC parameter.
2) You can pipe INSTANCES or TYPES to get-member
3) "Get-Member -Static" can be invoked as "gm -s"

Let's explore:

PS> Get-Date |Get-Member -Static

   TypeName: System.DateTime

Name            MemberType Definition
----            ---------- ----------
Compare         Method     static int Compare(System.DateTime t1, System.DateTime t2)
DaysInMonth     Method     static int DaysInMonth(int year, int month)
Equals          Method     static bool Equals(System.DateTime t1, System.DateTime t2), static bool Eq
FromBinary      Method     static System.DateTime FromBinary(long dateData)
FromFileTime    Method     static System.DateTime FromFileTime(long fileTime)
FromFileTimeUtc Method     static System.DateTime FromFileTimeUtc(long fileTime)
FromOADate      Method     static System.DateTime FromOADate(double d)
IsLeapYear      Method     static bool IsLeapYear(int year)
Parse           Method     static System.DateTime Parse(string s), static System.DateTime Parse(strin
ParseExact      Method     static System.DateTime ParseExact(string s, string format, System.IFormatP
ReferenceEquals Method     static bool ReferenceEquals(System.Object objA, System.Object objB)
SpecifyKind     Method     static System.DateTime SpecifyKind(System.DateTime value, System.DateTimeK
TryParse        Method     static bool TryParse(string s, System.DateTime&, mscorlib, Version=2.0.0.0
TryParseExact   Method     static bool TryParseExact(string s, string format, System.IFormatProvider
MaxValue        Property   static System.DateTime MaxValue {get;}
MinValue        Property   static System.DateTime MinValue {get;}
Now             Property   System.DateTime Now {get;}
Today           Property   System.DateTime Today {get;}
UtcNow          Property   System.DateTime UtcNow {get;}

PS> Get-Date |gm -s

   TypeName: System.DateTime

Name            MemberType Definition
----            ---------- ----------
Compare         Method     static int Compare(System.DateTime t1, System.DateTime t2)
DaysInMonth     Method     static int DaysInMonth(int year, int month)
Equals          Method     static bool Equals(System.DateTime t1, System.DateTime t2), static bool Eq
FromBinary      Method     static System.DateTime FromBinary(long dateData)
FromFileTime    Method     static System.DateTime FromFileTime(long fileTime)
FromFileTimeUtc Method     static System.DateTime FromFileTimeUtc(long fileTime)
FromOADate      Method     static System.DateTime FromOADate(double d)
IsLeapYear      Method     static bool IsLeapYear(int year)
Parse           Method     static System.DateTime Parse(string s), static System.DateTime Parse(strin
ParseExact      Method     static System.DateTime ParseExact(string s, string format, System.IFormatP
ReferenceEquals Method     static bool ReferenceEquals(System.Object objA, System.Object objB)
SpecifyKind     Method     static System.DateTime SpecifyKind(System.DateTime value, System.DateTimeK
TryParse        Method     static bool TryParse(string s, System.DateTime&, mscorlib, Version=2.0.0.0
TryParseExact   Method     static bool TryParseExact(string s, string format, System.IFormatProvider
MaxValue        Property   static System.DateTime MaxValue {get;}
MinValue        Property   static System.DateTime MinValue {get;}
Now             Property   System.DateTime Now {get;}
Today           Property   System.DateTime Today {get;}
UtcNow          Property   System.DateTime UtcNow {get;}

PS> [DateTime] |gm -s

   TypeName: System.DateTime

Name            MemberType Definition
----            ---------- ----------
Compare         Method     static int Compare(System.DateTime t1, System.DateTime t2)
DaysInMonth     Method     static int DaysInMonth(int year, int month)
Equals          Method     static bool Equals(System.DateTime t1, System.DateTime t2), static bool Eq
FromBinary      Method     static System.DateTime FromBinary(long dateData)
FromFileTime    Method     static System.DateTime FromFileTime(long fileTime)
FromFileTimeUtc Method     static System.DateTime FromFileTimeUtc(long fileTime)
FromOADate      Method     static System.DateTime FromOADate(double d)
IsLeapYear      Method     static bool IsLeapYear(int year)
Parse           Method     static System.DateTime Parse(string s), static System.DateTime Parse(strin
ParseExact      Method     static System.DateTime ParseExact(string s, string format, System.IFormatP
ReferenceEquals Method     static bool ReferenceEquals(System.Object objA, System.Object objB)
SpecifyKind     Method     static System.DateTime SpecifyKind(System.DateTime value, System.DateTimeK
TryParse        Method     static bool TryParse(string s, System.DateTime&, mscorlib, Version=2.0.0.0
TryParseExact   Method     static bool TryParseExact(string s, string format, System.IFormatProvider
MaxValue        Property   static System.DateTime MaxValue {get;}
MinValue        Property   static System.DateTime MinValue {get;}
Now             Property   System.DateTime Now {get;}
Today           Property   System.DateTime Today {get;}
UtcNow          Property   System.DateTime UtcNow {get;}

 

 

 

Now lets explore  how you access these.  You use "::" on types to invoke statics:

PS> [Datetime]::Today

Saturday, December 13, 2008 12:00:00 AM

PS> [Datetime]::IsLeapYear(2008)
True

 

 

 

So with that background, let's explore some of SYSTEM.ENVIRONMENT properties:

PS> [Environment] |gm -s

   TypeName: System.Environment

Name                       MemberType Definition
----                       ---------- ----------
Equals                     Method     static bool Equals(System.Object o...
Exit                       Method     static System.Void Exit(int exitCode)
ExpandEnvironmentVariables Method     static string ExpandEnvironmentVar...
FailFast                   Method     static System.Void FailFast(string...
GetCommandLineArgs         Method     static System.String[] GetCommandL...
GetEnvironmentVariable     Method     static string GetEnvironmentVariab...
GetEnvironmentVariables    Method     static System.Collections.IDiction...
GetFolderPath              Method     static string GetFolderPath(System...
GetLogicalDrives           Method     static System.String[] GetLogicalD...
ReferenceEquals            Method     static bool ReferenceEquals(System...
SetEnvironmentVariable     Method     static System.Void SetEnvironmentV...
CommandLine                Property   static System.String CommandLine {...
CurrentDirectory           Property   static System.String CurrentDirect...
ExitCode                   Property   static System.Int32 ExitCode {get;...
HasShutdownStarted         Property   static System.Boolean HasShutdownS...
MachineName                Property   static System.String MachineName {...
NewLine                    Property   static System.String NewLine {get;}
OSVersion                  Property   static System.OperatingSystem OSVe...
ProcessorCount             Property   static System.Int32 ProcessorCount...
StackTrace                 Property   static System.String StackTrace {g...
SystemDirectory            Property   static System.String SystemDirecto...
TickCount                  Property   static System.Int32 TickCount {get;}
UserDomainName             Property   static System.String UserDomainNam...
UserInteractive            Property   static System.Boolean UserInteract...
UserName                   Property   static System.String UserName {get;}
Version                    Property   static System.Version Version {get;}
WorkingSet                 Property   static System.Int64 WorkingSet {get;}

PS> [Environment]::MachineName
JPSW7-5
PS> [Environment]::OSVersion

          Platform ServicePack        Version            VersionString
          -------- -----------        -------            -------------
           Win32NT                    6.1.7004.0         Microsoft Windo...

PS> [Environment]::ProcessorCount
2
PS> [Environment]::UserInteractive
True
PS> [Environment]::UserDomainName
NTDEV
PS> [Environment]::UserName
jsnover
PS> [Environment]::SystemDirectory
C:\Windows\system32
PS>

 

 

 

Now let's explore some methods:

PS> [Environment]::GetLogicalDrives()
C:\
D:\
E:\
PS> [Environment]::GetEnvironmentVariable("PATH")
%SystemRoot%\system32\WindowsPowerShell\v1.0\;C:\Windows\system32;C:\Window
s;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\P
rogram Files\WTT 2.2\Client\;C:\PROGRA~1\CA\SHARED~1\SCANEN~1;C:\Program Fi
les\CA\eTrust Antivirus;c:\ps
PS> [Environment]::GetFolderPath()
Cannot find an overload for "GetFolderPath" and the argument count: "0".
At line:1 char:29
+ [Environment]::GetFolderPath <<<< ()
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

PS>

 

 

 

Notice the error I got for GetFolderPath() - it's complaining about the number of arguments it got.  So now let's learn the technique to discover method signatures.  If you specify a method and use "()", it invokes the method. If you don't provide the "()" and just specify the name, it give you information about the method:

PS> [Environment]::GetFolderPath

MemberType          : Method
OverloadDefinitions : {static string GetFolderPath(System.Environment+Speci
                      alFolder folder)}
TypeNameOfValue     : System.Management.Automation.PSMethod
Value               : static string GetFolderPath(System.Environment+Specia
                      lFolder folder)
Name                : GetFolderPath
IsInstance          : True

This tells you that the method takes one argument whose name is "folder" and whose type is System.Environment+SpecialFolder.  What the heck is that? 

PS> [System.Environment+SpecialFolder]

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
False    True     SpecialFolder                            System.Enum

 

Notice that it is an ENUM.  The great things about ENUMS is that when you specify an invalid value - it tells you what the valid values are:

PS> [Environment]::GetFolderPath("burp")
Cannot convert argument "0", with value: "burp", for "GetFolderPath" to typ
e "System.Environment+SpecialFolder": "Cannot convert value "burp" to type
"System.Environment+SpecialFolder" due to invalid enumeration values. Speci
fy one of the following enumeration values and try again. The possible enum
eration values are
"Desktop, Programs, Personal, MyDocuments, Favorites, St
artup, Recent, SendTo, StartMenu, MyMusic, DesktopDirectory, MyComputer, Te
mplates, ApplicationData, LocalApplicationData, InternetCache, Cookies, His
tory, CommonApplicationData, System, ProgramFiles, MyPictures, CommonProgra
mFiles"."

At line:1 char:29
+ [Environment]::GetFolderPath <<<< ("burp")
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

 

 

 

 

So let's try some of those values:

PS> [Environment]::GetFolderPath("cookies")
C:\Users\jsnover\AppData\Roaming\Microsoft\Windows\Cookies
PS> [Environment]::GetFolderPath("mypictures")
C:\Users\jsnover\Pictures

 

 

 

But wait - it's gets even better! 

Now let's pull it all together by realizing that ENUM is a type and that it has statics as well use that to find all the folderpaths:

PS> [Enum] |gm -s

   TypeName: System.Enum

Name              MemberType Definition
----              ---------- ----------
Equals            Method     static bool Equals(System.Object objA, Syst...
Format            Method     static string Format(type enumType, System....
GetName           Method     static string GetName(type enumType, System...
GetNames          Method     static System.String[] GetNames(type enumType)
GetUnderlyingType Method     static type GetUnderlyingType(type enumType)
GetValues         Method     static array GetValues(type enumType)
IsDefined         Method     static bool IsDefined(type enumType, System...
Parse             Method     static System.Object Parse(type enumType, s...
ReferenceEquals   Method     static bool ReferenceEquals(System.Object o...
ToObject          Method     static System.Object ToObject(type enumType...

PS> [Enum]::GetValues([System.Environment+SpecialFolder])
Desktop
Programs
Personal
Personal
Favorites
Startup
Recent
SendTo
StartMenu
MyMusic
DesktopDirectory
MyComputer
Templates
ApplicationData
LocalApplicationData
InternetCache
Cookies
History
CommonApplicationData
System
ProgramFiles
MyPictures
CommonProgramFiles

PS> foreach ($f in [Enum]::GetValues([System.Environment+SpecialFolder])) {
>> "{0,-20} - {1}" -f $f, [Environment]::GetFolderPath($f) }
>>
Desktop              - C:\Users\jsnover\Desktop
Programs             - C:\Users\jsnover\AppData\Roaming\Microsoft\Windows\S
tart Menu\Programs
Personal             - C:\Users\jsnover\Documents
Personal             - C:\Users\jsnover\Documents
Favorites            - C:\Users\jsnover\Favorites
Startup              - C:\Users\jsnover\AppData\Roaming\Microsoft\Windows\S
tart Menu\Programs\Startup
Recent               - C:\Users\jsnover\AppData\Roaming\Microsoft\Windows\R
ecent
SendTo               - C:\Users\jsnover\AppData\Roaming\Microsoft\Windows\S
endTo
StartMenu            - C:\Users\jsnover\AppData\Roaming\Microsoft\Windows\S
tart Menu
MyMusic              - C:\Users\jsnover\Music
DesktopDirectory     - C:\Users\jsnover\Desktop
MyComputer           -
Templates            - C:\Users\jsnover\AppData\Roaming\Microsoft\Windows\T
emplates
ApplicationData      - C:\Users\jsnover\AppData\Roaming
LocalApplicationData - C:\Users\jsnover\AppData\Local
InternetCache        - C:\Users\jsnover\AppData\Local\Microsoft\Windows\Tem
porary Internet Files
Cookies              - C:\Users\jsnover\AppData\Roaming\Microsoft\Windows\C
ookies
History              - C:\Users\jsnover\AppData\Local\Microsoft\Windows\His
tory
CommonApplicationData - C:\ProgramData
System               - C:\Windows\system32
ProgramFiles         - C:\Program Files
MyPictures           - C:\Users\jsnover\Pictures
CommonProgramFiles   - C:\Program Files\Common Files

 

Is that cool or what?

Enjoy!

 

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Leave a Comment
  • Please add 1 and 8 and type the answer here:
  • Post
  • hello,everyone here:

    I have a question:

     why powershell interpret "Environment.SpecialFolder" enum to "System.Environment+SpecialFolder"

    Isn't it look strange?

    another question:how powershell interpret .net EUNM type?

    http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx

    Thanks

  • PingBack from http://get-admin.com/blog/?p=212

  • Great post!  As an admin it took me a very long time to grasp .net objects, and there subtleties.  I really needed something like this a year ago!  Get-Member is the hardest thing to convey to a new admin, but once they get it... windows administration is never the same!

  • That *is* cool, but I get this:

    PS C:\Users\han\> [environment]::getfolderpath

    MemberType          : Method

    OverloadDefinitions : {static System.String GetFolderPath(SpecialFolder folder)}

    TypeNameOfValue     : System.Management.Automation.PSMethod

    Value               : static System.String GetFolderPath(SpecialFolder folder)

    Name                : GetFolderPath

    IsInstance          : True

    The parameter to GetFolderPath is simply SpecialFolder instead of 'System.Environment+SpecialFolder'.

    Could that be because I'm running CTP2?

  • @hans

    > Could that be because I'm running CTP2?

    No - it looks like someone refactored the class.  "System.Environment+SpecialFolder" means that the class is defined within the System.Environment class. System.SpecialFolder is defined as a peer class to System.Environment.  It shouldn't matter one way or the other - it should work the same.

    Jeffrey Snover [MSFT]

    Windows Management Partner Architect

    Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell

    Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

  • In my latest post Explore your [Environment] I said the following: PS&gt; [System.Environment+SpecialFolder]

  • Hi Jeffrey,

    it's really the GREAT post. Thanks a lot for that.

    David

  • The sentence in the 5th paragraph "Most properties are methods that you deal with are OBJECT properties and methods which is to say that they are the "properties of THAT object" or the "methods that can be invoked on THAT object"." makes no sense.

    I think what was meant was "Most Properties OR Methods that you deal with..."

    Thanks for this post - I wish I'd seen this a couple of years ago. It would have helped me 'get' how PowerShell leverages .NET.

  • When I type a method without the "()" i get no response at all, just returns to the PS prompt. This looks like a really cool feature that I would like to explore. Anyone have any ideas why this doesn't work?

  • Re Macattack's question:

    Omitting the () in a method call should return the method definition.

    For example:

    [system.int32]::tryparse (without the ()s) returns this, using CTP2:

    MemberType          : Method

    OverloadDefinitions : {static System.Boolean TryParse(String s, Int32& result), static System.Boolean TryParse(String s, NumberSt

                         yles style, IFormatProvider provider, Int32& result)}

    TypeNameOfValue     : System.Management.Automation.PSMethod

    Value               : static System.Boolean TryParse(String s, Int32& result), static System.Boolean TryParse(String s, NumberSty

                         les style, IFormatProvider provider, Int32& result)

    Name                : TryParse

    IsInstance          : True

  • I have the same issue as macattack:

    PS>[Environment]::GetFolderPath

    doesn't output the method signature

    I just get the prompt. Not output at all.

  • @COnstantine:

    Post the output of the following:

    PS> [Environment] |gm -s g*

    jps

  • @jps

    Maybe it's because I'm use PS 1.

    PS>"hello".CompareTo

    ...will give me a signature.

    But I can's get signatures for static members except via the method you suggest:

    PS> [Environment] |gm -s g*

      TypeName: System.Environment

    Name                    MemberType Definition

    ----                    ---------- ----------

    GetCommandLineArgs      Method     static System.String[] GetCommandLineArgs()

    GetEnvironmentVariable  Method     static System.String GetEnvironmentVariable(String variable), static System.Strin...

    GetEnvironmentVariables Method     static System.Collections.IDictionary GetEnvironmentVariables(), static System.Co...

    GetFolderPath           Method     static System.String GetFolderPath(SpecialFolder folder)

    GetLogicalDrives        Method     static System.String[] GetLogicalDrives()

    get_CommandLine         Method     static System.String get_CommandLine()

    get_CurrentDirectory    Method     static System.String get_CurrentDirectory()

    get_ExitCode            Method     static System.Int32 get_ExitCode()

    get_HasShutdownStarted  Method     static System.Boolean get_HasShutdownStarted()

    get_MachineName         Method     static System.String get_MachineName()

    get_NewLine             Method     static System.String get_NewLine()

    get_OSVersion           Method     static System.OperatingSystem get_OSVersion()

    get_ProcessorCount      Method     static System.Int32 get_ProcessorCount()

    get_StackTrace          Method     static System.String get_StackTrace()

    get_SystemDirectory     Method     static System.String get_SystemDirectory()

    get_TickCount           Method     static System.Int32 get_TickCount()

    get_UserDomainName      Method     static System.String get_UserDomainName()

    get_UserInteractive     Method     static System.Boolean get_UserInteractive()

    get_UserName            Method     static System.String get_UserName()

    get_Version             Method     static System.Version get_Version()

    get_WorkingSet          Method     static System.Int64 get_WorkingSet()

  • There is a known bug in PowerShell V1 where referencing a static method returned null instead of the method info. This was fixed for V2 and the fix is in the CTPs.

    -bruce

    ------------------

    Bruce Payette [MSFT]

  • I was hoping for an article that would tell me what string methods do, eg ToUpper vs ToUpperInvariant. And what parameters they required.

    I guess I'll keep on looking.

Page 1 of 2 (18 items) 12