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
  • I get the signature for the TryParseExact method but I don't seem to *get* it since this always blows up with an invalid 'argument count':

    [System.Globalization.CultureInfo]$provider = [System.Globalization.CultureInfo]::InvariantCulture

    $dateString = "Sun 15 Jun 2008 8:30 AM -06:00"

    $format = "ddd dd MMM yyyy h:mm tt zzz"

    $parsedDate = get-date

    $result = [DateTime]::TryParseExact($dateString, $format, $provider, [System.Globalization.DateTimeStyles]::None, [ref]$parsedDate)

    A call to ParseExact works:

    $result = [DateTime]::ParseExact($dateString, $format, $provider)

    What am I doing wrong?

  • I really want to "get" this, but it's really hard.

    ".Net provides a wonderful class called System.Environment that tells you all about your environment."

    My environment? What do you mean? The air I breathe? My environment right now is my office. Where do I find this class? What are the other classes? Why is system.environment so great?

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

    A type of what? A type of pizza? A type of typewriter? Give me some context here. What is a type and how does it relate to my 'environment' or a class?

    And what's with the example? Were were looking at Environment? Now we've moved to System.Diagnostics and I can drop the "system"? What??

    Don't get me wrong, I really, truly and deeply appreciate anyone willing to try to explain these concepts on a forum like this, and I know I have so much to learn, but just a little bit more context would go a very long way.

    Thanks

  • Hi

    Amazing post and you posted it 4 years ago but it still very helpful..

    Thanks

    aman

    newdelhipowershellusergroup.blogspot.in

Page 2 of 2 (18 items) 12