Quantcast
Channel: Hey, Scripting Guy! Blog
Viewing all 3333 articles
Browse latest View live

PowerTip: Discover PowerShell Cmdlets that Accept Array of Strings

$
0
0

Summary: Learn how to find Windows PowerShell cmdlets that accept an array of strings for parameter input.

Hey, Scripting Guy! Question How can I find all the Windows PowerShell cmdlets that accept an array of strings for parameter input?

Hey, Scripting Guy! Answer Import all modules, then use the Get-Command cmdlet and the ParameterName parameter to look for [string[]] (if you use aliases, the first command shortens to gmo -l | ipmo):

Get-Module –list | import-Module

Get-Command –ParameterType [string[]]

The following script counts parameter types—first it counts arrays of strings, then it counts strings (gcm is an alias for Get-Command):

PS C:\> gcm -ParameterType [string[]] | measure

 

Count    : 905

Average  :

Sum      :

Maximum  :

Minimum  :

Property :

 

PS C:\> gcm -ParameterType [string] | measure

 

Count    : 2407

Average  :

Sum      :

Maximum  :

Minimum  :

Property :


Export User Names and Proxy Addresses to CSV File

$
0
0

Summary: Microsoft Scripting Guy Ed Wilson talks about using Windows PowerShell to export user names and proxy addresses to a CSV file from Active Directory.

Hey, Scripting Guy! Question Hey, Scripting Guy! I am trying to produce a report of our users in Active Directory and their associated proxy addresses. I want it in Excel, so I am using the Export-CSV cmdlet. The issue is that although I can get the user names just fine, the proxy addresses come back with:

Microsoft.ActiveDirectory.Management.ADPropertyValueCollection

This does not happen when I print to the screen, only when I export it to a CSV file. Help! This is quite annoying.

—JF

Hey, Scripting Guy! Answer Hello JF,

Microsoft Scripting Guy, Ed Wilson, is here. It is a new week down here in Charlotte, North Carolina in the United States. The weather has taken a turn for the worse, so instead of getting a daily deluge of rain, we now have hot and humid. Personally, I think I already miss the rain—I am not a huge fan of hot and humid. Luckily, I do not have to go out too often (one of the great things about working from home), so I can sit in front of a couple of fans, check my email, and get right to work.

The issue with a multivalued attribute

The issue with a multivalued attribute, such as the ProxyAddresses attribute, is that it is an array. This means it contains multiple values that are associated with a single attribute.This makes sense for something like ProxyAddresses because there could be one or more proxy addresses defined for any particular user in Active Directory Domain Services (AD DS). For something like street address, there is only one value permitted for that attribute because it accepts a single value only.

When I run the following commands, I can easily replicate the issue with the multivalued attribute. (This is a single, logical line command. I broke it at the pipe to display in the blog).

Get-ADUser -Filter * -SearchBase 'ou=testou,dc=iammred,dc=net' -Properties proxyaddresses |

select name, proxyaddresses | Export-CSV -Path c:\fso\proxyaddresses.csv –NoTypeInformation

When I run the command, and open the CSV file in Microsoft Excel, I am greeted with the following output: 

Image of spreadsheet

Fixing the issue with multivalued attributes

Perhaps the easiest way to fix the issue with the multivalued ProxyAddresses attribute is to create a custom Select-Object property, then index directly into the array to pull out proxy address 1 and proxy address 2. To do this, I use a hash table to create a new property. The hash table requires two elements: the label and the expression. The label is a string, and the expression is a script block. In Windows PowerShell terms, this means that I can basically do anything I need to do inside the expression element.

Get-ADUser -Filter * -SearchBase 'ou=testou,dc=iammred,dc=net' -Properties proxyaddresses |

select name, @{L='ProxyAddress_1'; E={$_.proxyaddresses[0]}},

@{L='ProxyAddress_2';E={$_.ProxyAddresses[1]}} |

Export-Csv -Path c:\fso\proxyaddresses.csv -NoTypeInformation

I then open the CSV file in Microsoft Excel. The command is shown here:

PS C:\> Get-ADUser -Filter * -SearchBase 'ou=testou,dc=iammred,dc=net' -Properties pr

oxyaddresses | select name, @{L='ProxyAddress_1'; E={$_.proxyaddresses[0]}}, @{L='Pro

xyAddress_2';E={$_.ProxyAddresses[1]}} | Export-Csv -Path c:\fso\proxyaddresses.csv -

NoTypeInformation

Image of command

The Excel spreadsheet appears, and now I have two columns worth of proxy addresses as shown in the following image:

Image of spreadsheet

JF, that is all there is to using Windows PowerShell to retrieve multivalued attributes and write them to a CSV file. Join me tomorrow when I will talk about more cool Windows PowerShell stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

PowerTip: Discover which PowerShell Cmdlets Have Parameter to Accept Specific Type

$
0
0

Summary: Learn how to find Windows PowerShell cmdlets that have a specific parameter that accepts specific types.

Hey, Scripting Guy! Question How can I find all Windows PowerShell cmdlets that have a parameter named ComputerName that accepts an array of strings?

Hey, Scripting Guy! Answer Import all the modules, then use the Get-Command cmdlet to look for a ParameterName of ComputerName and a ParameterType of [string[]]:

Get-Module –list | import-Module

Get-Command –ParameterType [string[]] –ParameterName ComputerName

The following script counts how many cmdlets have a parameter named ComputerName that accepts a string, and how many accept an array of strings:

PS C:\> gcm -ParameterType [string] -ParameterName computername | measure

 

Count    : 549

Average  :

Sum      :

Maximum  :

Minimum  :

Property :

 

PS C:\> gcm -ParameterType [string[]] -ParameterName computername | measure

 

Count    : 204

Average  :

Sum      :

Maximum  :

Minimum  :

Property :

Write Users and Proxy Addresses to CSV by Using PowerShell

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about writing all proxy addresses and user names to a CSV file by using Windows PowerShell.

Hey, Scripting Guy! Question Hey, Scripting Guy! Yesterday’s blog post, Export User Names and Proxy Addresses to CSV File, showed me an easy way to get a couple of proxy addresses from Active Directory, but all users do not consistently have only one or two addresses. Some users have as many as four or five. I want to know exactly how many I have, and I need to know all of the addresses. Can you help?

—PQ

Hey, Scripting Guy! Answer Hello PQ,

Microsoft Scripting Guy, Ed Wilson, is here. Well, it has not gotten any cooler today down here in Charlotte, North Carolina. But the evenings are not too bad after the sun goes down. The mornings are actually quite nice right before the sun comes up. I am trying to figure out a way to do the siesta thing down here, but for some strange reason I cannot catch on. Bummer—it is a great idea.

I decided to break down and write a script to solve this issue. I probably could have done it in a one-liner, but it begins to get too complicated, convoluted, and cumbersome. In the end, many times a simple script is much better than a very hard to read one-liner…at least in my mind.

Gather the users information

The first thing I do is gather together all of the user names with which I want to work. I make sure to pick up the ProxyAddresses attribute because it is not selected by default. I store all of the returned user objects in a variable named $users. This line of script is showne here:

$users = Get-ADUser -Filter * -SearchBase 'ou=testou,dc=iammred,dc=net' -Properties proxyaddresses

Walk through the users

I need to walk through my collection of users. I do this by using the Foreach language statement. Inside the loop, I will use $u to refer to a specific user. This script is shown here:

Foreach ($u in $users)

 {

Now I create an ordered dictionary object. This is a new feature in Windows PowerShell 3.0. It acts like a hash table, except that it is ordered. The key to success is that [ordered] MUST appear right in front of the @ symbol. In addition, I need to completely delete the variable after I am done using it. If I cast the ordered dictionary to a hash table, I lose the ordered attribute. There is no way to specify how I am going to order the dictionary object—it does it by maintaining the order in which the items become added to the dictionary. Here, I create the ordered dictionary object, and then I add the user name to it:

$proxyAddress = [ordered]@{}

 $proxyAddress.add("User",$u.name)

I want to add all of the proxy addresses. To do this, I use the Count property from the array of ProxyAddresses, and I use the For statement to count actions for each of the addresses. I then use the Add method to add the ProxyAddresses values to a new field named after the order of ProxyAddress. This section of script is shown here:

For ($i = 0; $i -le $u.proxyaddresses.count; $i++)

   {

    $proxyAddress.add("ProxyAddress_$i",$u.proxyaddresses[$i])

    } #end for

I cast the ordered dictionary to a PSCustomObject, and then I pipe it to the Export-CSV cmdlet. The key here is to remember to use the –NoTypeInformation switch or the newly created CSV file will not display properly in Microsoft Excel (due to the entrenched type information). Now I remove the variable. This is shown here:

[pscustomobject]$proxyAddress |

  Export-Csv -Path c:\fso\proxyaddresses.csv -NoTypeInformation –Append -Force

  Remove-Variable -Name proxyAddress } #end foreach 

The last thing I do in my script is use Invoke-Item to open the CSV file. By default, this opens in Excel— that for my purposes is fine. The following image illustrates the newly created Excel spreadsheet:

Image of spreadsheet

PQ, that is all there is to using Windows PowerShell to display all proxy address values. Join me tomorrow when I will talk about more cool Windows PowerShell stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

PowerTip: Generate an HTML Battery-Life Report in PowerShell

$
0
0

Summary: Use Windows PowerShell and generate an HTML battery-life report.

Hey, Scripting Guy! Question How can I generate an HTML battery-life report on my laptop to see expected battery life?

Hey, Scripting Guy! Answer Open Windows PowerShell as an administrator and type the following command:

powercfg /batteryreport

The command reports a destination for the report that you open by using the Invoke-Item cmdlet (ii is an alias):

ii C:\battery-report.html

Exploring Active Directory Data Types with PowerShell

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to explore Active Directory data types.

Hey, Scripting Guy! Question Hey, Scripting Guy! I need a way to see the data types of various Active Directory attributes. I know I can look up this information on MSDN, but I want to explore these on my own. Have you written an Active Directory schema browser?

—AB

Hey, Scripting Guy! Answer Hello AB,

Microsoft Scripting Guy, Ed Wilson, is here. You know, more than five years ago I wrote an Active Directory schema browser in Windows PowerShell. I just looked at it again, and I will be honest, I was not really impressed. It seems that I have learned a bit about Windows PowerShell in the intervening years. But one thing I did not remember, was how I actually accessed the Active Directory schema in the first place. So from that 116 line Windows PowerShell script, the following line of script is about all I really needed. Good thing I saved that script, or I might have been in trouble. As I recall, it is not something that is easily found.

Use PowerShell to retrieve the Active Directory schema

I use the [DirectoryServices.ActiveDirectory.ActiveDirectorySchema] .NET Framework class and the GetCurrentSchema static to retrieve the current schema. I store the returned ActiveDirectorySchema object in a variable named $schema. This technique is shown here:

$schema =[DirectoryServices.ActiveDirectory.ActiveDirectorySchema]::GetCurrentSchema()

Now I look inside the $schema variable to see what I have obtained, as shown here:

PS C:\> $schema

 

SchemaRoleOwner                            Name

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

dc1.iammred.net                            CN=Schema,CN=Configuration,DC=iammred,...

I decide to use Get-Member to see what this object will enable me to do. Here is the command and the results:

PS C:\> $schema | Get-Member

 

   TypeName: System.DirectoryServices.ActiveDirectory.ActiveDirectorySchema

 

Name                     MemberType Definition

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

Dispose                  Method     void Dispose(), void IDisposable.Dispose()

Equals                   Method     bool Equals(System.Object obj)

FindAllClasses           Method     System.DirectoryServices.ActiveDirectory.Read...

FindAllDefunctClasses    Method     System.DirectoryServices.ActiveDirectory.Read...

FindAllDefunctProperties Method     System.DirectoryServices.ActiveDirectory.Read...

FindAllProperties        Method     System.DirectoryServices.ActiveDirectory.Read...

FindClass                Method     System.DirectoryServices.ActiveDirectory.Acti...

FindDefunctClass         Method     System.DirectoryServices.ActiveDirectory.Acti...

FindDefunctProperty      Method     System.DirectoryServices.ActiveDirectory.Acti...

FindProperty             Method     System.DirectoryServices.ActiveDirectory.Acti...

GetDirectoryEntry        Method     adsi GetDirectoryEntry()

GetHashCode              Method     int GetHashCode()

GetType                  Method     type GetType()

RefreshSchema            Method     void RefreshSchema()

ToString                 Method     string ToString()

Name                     Property   string Name {get;}

SchemaRoleOwner          Property   System.DirectoryServices.ActiveDirectory.Dire...

There were two properties displayed earlier when I examined the $schema variable. There are also a bunch of methods. These methods seem to be rather interesting. First, let me look at a User class:

PS C:\> $schema.FindClass("user")

 

Name                            : user

CommonName                      : User

Oid                             : 1.2.840.113556.1.5.9

Description                     :

IsDefunct                       : False

PossibleSuperiors               : {msExchSystemObjectsContainer, builtinDomain,

                                  organizationalUnit, domainDNS}

PossibleInferiors               : {ms-net-ieee-80211-GroupPolicy,

                                  msExchActiveSyncDevices,

                                  ms-net-ieee-8023-GroupPolicy, classStore...}

MandatoryProperties             : {cn, instanceType, nTSecurityDescriptor,

                                  objectCategory...}

OptionalProperties              : {accountExpires, accountNameHistory,

                                  aCSPolicyName, adminCount...}

AuxiliaryClasses                : {bootableDevice, samDomainBase,

                                  simpleSecurityObject, ieee802Device...}

SubClassOf                      : organizationalPerson

Type                            : Structural

SchemaGuid                      : bf967aba-0de6-11d0-a285-00aa003049e2

DefaultObjectSecurityDescriptor : System.DirectoryServices.ActiveDirectorySecurity

Now let me look at the required properties of a User class:

$schema.FindClass("user").mandatoryproperties

The command returns a lot of information, but it seems to be rather cluttered. Here is the output:

Image of command output

I decide to pipe the output to the Out-GridView cmdlet. This provides me with a nice graphical tool and enables me to view the information more easily. Here is the command (ogv is an alias for the Out-GridView cmdlet):

$schema.FindClass("user").mandatoryproperties | ogv

The output from the previous command is represented in the following image:

Image of command output

Now I want to look at the User class optional attributes. To do this, I use the following command:

$schema.FindClass("user").optionalproperties | Out-GridView

There are hundreds of optional attributes for the user class object. They all appear in the following Grid View. As you can see, there is also a great deal of useful information available here.

Image of command output

The cool thing about using the Out-GridView tool is that I can easily filter the display to permit further discovery. The image that follows shows IsSingleValued equal to False (indicating multivalued attributes), IsInGlobalCatalog equal to True, IsIndexed equal to True, and it is sorted by Syntax.

Image of command output

In addition to using Out-GridView, I can use normal Windows PowerShell commands. For example, I can use the following command to find all the different types of unique syntax:

$schema.FindClass("user").optionalproperties | select syntax -Unique

The command and associated output are shown here:

Image of command output

AB, that is all there is to using Windows PowerShell to explore the Active Directory Schema. Join me tomorrow when I will talk about more cool Windows PowerShell stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

PowerTip: Count Your PowerShell Scripts

$
0
0

Summary: Learn how to count how many PowerShell scripts you have written.

Hey, Scripting Guy! Question My boss asked me how many Windows PowerShell scripts I have written. I keep all my scripts in a specific folder. How can I use Windows PowerShell to count them?

Hey, Scripting Guy! Answer Use the Get-ChildItem cmdlet (dir is an alias), and specify the path, a filter, and the Recurse parameter; then pipe the results to the Measure-Object cmdlet:

dir -Path C:\data -Filter *.ps1 -Recurse | measure

Use PowerShell to Report and Set Monitor Brightness

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to report and set monitor brightness.

Microsoft Scripting Guy, Ed Wilson, is here. Today I was exploring the Root/WMI namespace in Windows Management Instrumentation (WMI) on my Windows 8 laptop. I happened to run across a few WMI classes that I had not messed around with before. I like to use the Get-CimClass cmdlet from Windows PowerShell 3.0 for this kind of explorations because it supports tab completion and other features that make this exploration easy.

Look for WMI classes related to monitor brightness

So I was initially looking for anything related to monitors. And as I looked at what scrolled by, I saw that there were classes related to monitor brightness. So I decided to modify my query a bit to include things related to monitor brightness. I derived the following command, and achieved the results shown here:

PS C:\> Get-CimClass -Namespace root/WMI -ClassName *monitorbrightness*

 

   NameSpace: ROOT/wmi

 

CimClassName                        CimClassMethods      CimClassProperties

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

WmiMonitorBrightnessEvent           {}                   {SECURITY_DESCRIPTOR, TI...

WmiMonitorBrightness                {}                   {Active, CurrentBrightne...

WmiMonitorBrightnessMethods         {WmiSetBrightness... {Active, InstanceName}

I thought I would try to query the WmiMonitorBrightness WMI class first because it looks like it would report first. So I edited my previous line and changed from Get-CimClass to Get-CimInstance. Here is the command, and the output associated with the command:

PS C:\> Get-Ciminstance -Namespace root/WMI -ClassName WmiMonitorBrightness

 

Active            : True

CurrentBrightness : 100

InstanceName      : DISPLAY\LEN40B2\4&3062e51&0&UID67568640_0

Level             : {0, 1, 2, 3...}

Levels            : 101

PSComputerName    :

So without any reference material, I can see that the current brightness of my laptop monitor is 100. This is probably a percentage setting. I connect to MSDN, and look up WmiMonitorBrightness class. Sure enough it is the current brightness of the monitor as a percentage. The Level property lists supported values for CurrentBrightness. I check it by piping the results to the Select-Object cmdlet. Here is a sample of the output:

PS C:\> Get-Ciminstance -Namespace root/WMI -ClassName WmiMonitorBrightness | select

-ExpandProperty level

0

1

2

3

4

<truncated>

The strange thing is that Level lists how many different levels are available. The value of 101 makes sense because Level begins with 0 and ends with 100.

Set the brightness

To set the brightness on my laptop display monitor, I figure I can use the WmiMonitorBrightNessMethods WMI class. While I have MSDN open, I check out WmiMonitorBrightnessMethods class, and it appears that I will be able to use it to set my monitor brightness:

PS C:\> Get-CimClass -Namespace root/WMI -ClassName WmiMonitorBrightnessMethods

   NameSpace: ROOT/WMI

 

CimClassName                        CimClassMethods      CimClassProperties

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

WmiMonitorBrightnessMethods         {WmiSetBrightness... {Active, InstanceName}

There are only two properties: Active and InstanceName. I decide to look at them. Here is the result:

PS C:\> Get-CimInstance -Namespace root/WMI -ClassName WmiMonitorBrightnessMethods

                      Active InstanceName                PSComputerName

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

                        True DISPLAY\LEN40B2\4&3062e5...

Examine the WMI class methods

So, the WmiMonitorBrightnessMethods WMI class looks like it might be useful. Now, I want to look at the method information in more detail:

PS C:\> $wmi.CimClassMethods

 

Name                            ReturnType Parameters           Qualifiers

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

WmiSetBrightness                   Boolean {Brightness, Time... {Implemented, Wmi...

WmiRevertToPolicyB...              Boolean {}                   {Implemented, Wmi...

WmiSetALSBrightnes...              Boolean {State}              {Implemented, Wmi...

WmiSetALSBrightness                Boolean {Brightness}         {Implemented, Wmi...

I see that there are four methods for the WmiMonitorBrightnessMethods class. The method that looks like it is the best one for my needs is the WmiSetBrightness method. It takes two parameters that I want to look at in more detail. So I adjust my query to focus on it. I use the Item method to specify which method I want to look at. The command is shown here:

PS C:\> $wmi.CimClassMethods.Item('wmiSetBrightness')

 

Name                            ReturnType Parameters           Qualifiers

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

WmiSetBrightness                   Boolean {Brightness, Time... {Implemented, Wmi...

But the parameters information is still truncated. So I add Parameters to the end of my query and arrive at the following:

PS C:\> $wmi.CimClassMethods.Item('wmiSetBrightness').parameters

 

Name                               CimType Qualifiers           ReferenceClassName

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

Brightness                           UInt8 {ID, in}

Timeout                             UInt32 {ID, in}

Cool. Now I know the two parameters that I need to use to call this method. Brightness is expressed as a percentage, and Timeout is expressed in seconds.

I use the Get-WmiObject cmdlet to query the WmiMonitorBrightnessMethods WMI class, and store the returned object in a variable as shown here:

$monitor = Get-WmiObject -ns root/wmi -class wmiMonitorBrightNessMethods

Now, I call the WmiSetBrightNess method and specify that I want the monitor to be at 80% and request that it do so in 10 seconds. Here is the command:

$monitor.WmiSetBrightness(80,10)

Cool! It works. Not sure how I will use this, but it does work.

Well, that is all there is to using the WMI classes to set monitor brightness. Join me tomorrow when I will talk about more cool Windows PowerShell stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy


PowerTip: Create a New GUID by Using PowerShell

$
0
0

Summary: Easily use Windows PowerShell to create a new GUID.

Hey, Scripting Guy! Question How can I use Windows PowerShell to easily create a new GUID?

Hey, Scripting Guy! Answer Use the [guid] type accelerator, and call the NewGuid static method:

[guid]::NewGuid()

Use PowerShell to Inventory Modern Apps in Windows 8

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to look at modern apps in Windows 8.

Microsoft Scripting Guy, Ed Wilson, is here. One of the things I love about Windows 8 (including my Surface RT) are the modern apps. They are, well, just so modern. Of course, what I really like about them are the Windows PowerShell cmdlets that are part of the Appx module. Here are the cmdlets and functions from that module:

PS C:\> Get-Command -Module appx

 

CommandType     Name                                               ModuleName

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

Function        Get-AppxLastError                                  Appx

Function        Get-AppxLog                                        Appx

Cmdlet          Add-AppxPackage                                    Appx

Cmdlet          Get-AppxPackage                                    Appx

Cmdlet          Get-AppxPackageManifest                            Appx

Cmdlet          Remove-AppxPackage                                 Appx

Using Get-AppxPackage

I can use the Get-AppxPackage cmdlet to view application packages for my current user ID. But If I want to view packages from all users, I need to start Windows PowerShell with Admin rights. To see all of the modern apps that are installed for my sign-in ID, I use the Get-AppxPackage cmdlet with no parameters. An example of this is shown here:

Image of command output

Because the cmdlet displays packages for my current sign-in ID, the output does not include user information by default. When I use the –AllUsers switch, PackageUserInformation becomes available, as shown here:

Get-AppxPackage –AllUsers

The command and the associated output are shown in the image that follows.

Image of command output

I can also specify a particular user. This user can be from the domain (if the computer is domain-joined), or it can be from the local account database. In the following example, I choose a user from the local account database. The syntax is computername\username.

Get-AppxPackage -User edlt\ed

Note  Like when I use the cmdlet to retrieve current sign-in user information, PackageUserInformation does not display by default when retrieving specific user information.

The cool thing is that with Windows PowerShell, I can also sort by group and do any parsing that I feel I should do. For example, I might want to see how many different users installed modern applications on this computer. I do this by using the –Unique switch in conjunction with the Select-Object cmdlet as follows:

Get-AppxPackage -AllUsers | select packageuserinformation –Unique

The command and its associated output are shown here:

Image of command output

It also appears that I have several packages that are already downloaded, but not yet installed. I see this by looking at "Unknown user: Staged.” So I query for all users, and I select the name and version of the product when the user contains the word "staged." Here is the command and the associated output:

PS C:\> Get-AppxPackage -AllUsers | where packageuserinformation -match staged |

select name, version

 

Name                                       Version

----                                       -------

5269FriedChicken.YouTubeVideosDownloader   1.0.0.132

24264Craftbox.Showtime                     6.0.0.19

LenovoCorporation.LenovoSettings           1.2.0.13723

PixelTuckerPtyLtd.MetroTwit                1.0.0.126

PixelTuckerPtyLtd.MetroTwit                1.0.0.127

Because I see there are two copies of MetroTwit staged, I decide to look at information concerning my version of MetroTwit. To do this, I use the –Name parameter as shown here:

PS C:\> Get-AppxPackage -Name *metrotwit*

 

Name              : PixelTuckerPtyLtd.MetroTwit

Publisher         : CN=34979D06-CC5C-48B5-BB2F-8EF70E1A425E

Architecture      : Neutral

ResourceId        :

Version           : 1.0.0.116

PackageFullName   : PixelTuckerPtyLtd.MetroTwit_1.0.0.116_neutral__5kbmb3e034y6r

InstallLocation   : C:\Program Files\WindowsApps\PixelTuckerPtyLtd.MetroTwit_1.0.0.1

                    16_neutral__5kbmb3e034y6r

IsFramework       : False

PackageFamilyName : PixelTuckerPtyLtd.MetroTwit_5kbmb3e034y6r

PublisherId       : 5kbmb3e034y6r

Cool. I see that I am using an older version of MetroTwit. I already have two updated versions on my system, and I simply need to upgrade the package.

Well, that is all there is to exploring Appx packages with Windows PowerShell. Join me tomorrow when I will talk about more cool Windows PowerShell stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

PowerTip: Use PowerShell to View App Package Installation Log

$
0
0

Summary: Learn how to use Windows PowerShell to view the app package installation log.

Hey, Scripting Guy! Question How can I use Windows PowerShell in Windows 8 to review the app package installation log for errors, warnings, and additional information about installation packages?

Hey, Scripting Guy! Answer Use the Get-AppxLog cmdlet:

Get-AppxLog

Weekend Scripter: Use PowerShell to Uninstall Modern Apps

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about uninstalling modern apps.

Microsoft Scripting Guy, Ed Wilson, is here. It is the weekend here in Charlotte, North Carolina. The Scripting Wife decided that we would go to the Blue Ridge Classic Horse Show today, so she actually got up early, and got everything ready for the trip. She even packed a feed sack (for me—not for the horses). Personally, I like watching the little Roadster Ponies, but Teresa likes the Friesians. Our good friend, Microsoft PowerShell MVP, Jeff Wouters, even arranged for us to go see some Friesian horses in Friesland when we were in Holland. They are impressive beasts. Here is a picture I took during the show.

Photo of horse

Over the years, the Scripting Wife and I have been to several horse shows, and one thing that is interesting is that over time our tastes have changed. I used to like the five-gaited show pleasure horses. She used to like the Western-saddle bred horses before she fell in love with the Friesians. The same thing is true of software, especially with the modern apps. They are so easy to download and install from the store, that I hardly give much thought to them. I download them, and if I do not use them very much, I uninstall them. Here is part of my Start screen:

Image of screen

To uninstall a modern app, I use the Remove-AppxPackage. The problem is that this cmdlet requires a package name, which is generally really, really long. It does not accept wildcard characters either. In the following image, I attempt to remove a modern app, but I get an error message. The message is a bit misleading because it complains that I do not have the software package installed—but of course, I do.

Image of error message

The cause of the error message is that it is looking literally for a package named *pricedetective* and it is not finding it. The solution is to use the Get-AppxPackage cmdlet to find the package. This is because the Windows PowerShell Get-AppxPackage cmdlet accepts wildcard characters for the package name. This is shown here:

Image of command

Because Remove-AppxPackage accepts piped input, I can use wildcard characters to find the package with Get-AppxPackage, and then send the results over the pipeline to remove the package. Depending on how long it takes to uninstall the package, a progress bar may appear at the top of the Windows PowerShell console to indicate that the command is working. The command is shown here:

Get-AppxPackage -Name *pricedetective* | Remove-AppxPackage

Removing multiple apps

Remember (I have said it many times)…PowerShell is PowerShell is PowerShell. This means that properly designed, well-behaved Windows PowerShell cmdlets all work the same. This means I can use standard Windows PowerShell techniques such as arrays, the Foreach-Object, and the pipeline. By putting them together, I can remove multiple applications as easily as I can remove one package. The following command removes a couple of applications that I have installed on my computer:

"*greenville*","*magnetophone*" | foreach {Get-AppxPackage $_ | Remove-AppxPackage}

While the command runs, it creates a progress bar as shown here:

Image of progress bar

When I am done, I run the Get-AppxPackage command to ensure that I did indeed remove the applications. Nothing returns, which means they are gone.

"*greenville*","*magnetophone*" | foreach {Get-AppxPackage $_ }

I bounce back to my Start screen. Sure enough—it is cleaned up a bit.

Image of screen

I have the apps cleaned up, and now the Roadster Pony-Limit Pony class is up, so I have to go. Who knows, I might find another favorite class. The only problem is that there is no Remove-ShowPony cmdlet. Oh well. I hope you enjoy the rest of your weekend. Join me tomorrow for more cool Windows PowerShell stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

PowerTip: Open the Windows PowerShell ISE from Inside the Console

$
0
0

Summary: Learn how to open the Windows PowerShell ISE from inside the Windows PowerShell console.

Hey, Scripting Guy! Question I ran a script in the Windows PowerShell console that generated an error, so how can I open the script in the Windows PowerShell ISE to edit it?

Hey, Scripting Guy! Answer Type ISE and the path to the script, so to edit your Windows PowerShell console profile, type:

Ise $profile

Weekend Scripter: Cheesy Script to Set Speaker Volume

$
0
0

Summary: Set the speaker volume by using Windows PowerShell—the cheesy script way.

Microsoft Scripting Guy, Ed Wilson, is here. It is still the weekend, and that means I get a chance to play. Speaking of playing…

Yesterday the Scripting Wife and I were at the horse show in Ashville. For us, it was play. For the people participating in the show, it is very serious business. Anyway, I got to see my favorites: the Roadster Ponies. These little dudes are quick and fun to watch. Here is a cool picture I took:

Photo of horses

Anyway, speaking of cool…

Here is a cheesy script I wrote on the way back home for setting the volume of my speakers.

There is always a right way, a wrong way, a Windows PowerShell way, and a cheesy way to do things. The exact method I choose to do something depends on my personal use-case scenario. For something like setting speaker volume, I want to be able to programmatically set my volume to maximum or to minimum when I am listening to Internet radio, watching a video, or on a conference call.

Why is the script cheesy? Well, because it uses the old-fashioned SendKeys method from the old VBScript WshShell object. SendKeys can be very unreliable, and is not really recommended for automation solutions. But for something like this, it works just fine.

So why cheesy in the first place? Well, because really automating sound requires some heavy duty excursions into native code. A good example is a script by JRV in the Script Center Repository: PowerShell Set PC Volume Control.

So what does my script do?

I wrote a function that I can call from wherever I am in the Windows PowerShell environment. Obviously, I could not call it Set-Volume because that is already a CIM function in Windows 8 that deals with storage. So I called it Set-SpeakerVolume. The heart of the function is where I use SendKeys to send [char]174 (the down volume key on my laptop) or [char]175 (the up volume key on my laptop). 

By experimentation, I figured out that each key press raised or lowered the volume by two. Therefore I use the 1..50 array to send 50 key presses. The [char]173 key displays only the volume arrow, and it does not raise or lower the volume. I set this as the default action of the function so I can quickly see what the current volume is set to, as shown in the following image:

Image of menu

The complete Set-SpeakerVolume function is shown here:

Function Set-SpeakerVolume

{ Param (

  [switch]$min,

  [switch]$max)

 

  $wshShell = new-object -com wscript.shell

 

  If ($min)

  {1..50 | % {$wshShell.SendKeys([char]174)}}

  ElseIf ($max)

  {1..50 | % {$wshShell.SendKeys([char]175)}}

  Else

  {$wshShell.SendKeys([char]173)} }

Hope you are having a great day, and join me tomorrow for a new week on the Hey, Scripting Guy! Blog. Until then, take care.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Peace.

Ed Wilson, Microsoft Scripting Guy 

PowerTip: Automatically Open a Script in the PowerShell ISE

$
0
0

Summary: Learn how to automatically open a script in the Windows PowerShell ISE.

Hey, Scripting Guy! Question How can I automatically open a script in a new pane inside the Windows PowerShell ISE?

Hey, Scripting Guy! Answer Type psedit and the file path inside the ISE console pane:

psedit C:\fso\a.ps1


Add a Couple of Functions to PowerShell Profile

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, adds a couple of new functions to his Windows PowerShell console profile.

Microsoft Scripting Guy, Ed Wilson, is here. I have heard that necessity is the mother of invention. For me, annoyance is the mother of scripting. What I mean is that when it comes time for me to write a script (something short and quick), I only do it after I am tired of typing the same command over and over again. For example, consider the first two functions I recently added to my Windows PowerShell profile…

Load and unload modules

Everyone knows we have automatic module loading in Windows PowerShell 3.0. But not everyone knows that when it comes time to use Get-Command, if I have not loaded the modules, an error generates, as shown here.

Image of error message

If this is the case, why don’t I just add the command to load all modules into my profile? The reason is speed of launching. For example, on my laptop, it consistently takes 16 seconds to load all of my modules. This is shown here:

PS C:\> Measure-Command {Import-AllModules}

Warning:  To run some commands exposed by this module on Windows Vista, Windows

Server 2008, and later versions of Windows, you must start an elevated Windows

PowerShell console.

 

Days              : 0

Hours             : 0

Minutes           : 0

Seconds           : 16

Milliseconds      : 43

Ticks             : 160435770

TotalDays         : 0.000185689548611111

TotalHours        : 0.00445654916666667

TotalMinutes      : 0.26739295

TotalSeconds      : 16.043577

TotalMilliseconds : 16043.577

I want to be able to load or to unload all of the modules, but do it only when I need to do so. Therefore, this becomes a good excuse for writing a couple of functions.

I have been typing the commands to load and to unload all modules for at least a year (as long as I have been using Windows PowerShell 3.0). Finally, it got to me, and I decided to write the simple functions that follow. Oh by the way, to make the functions easier to use, I created a couple of aliases for them too. Here are the two functions:

Function Import-AllModules

{Get-Module -ListAvailable | Import-Module}

 

Function Remove-AllModules

{Get-Module -ListAvailable | Remove-Module}

Set-Alias -Name ram -Value Remove-AllModules

Set-Alias -Name iam -Value import-allmodules

Finding commands

Get-Command works great. But the default output is not what I normally would do. For example, because of all the cmdlets and functions, the output invariably scrolls, so I need to pipe the results to More. In addition, I normally am looking for cmdlets from the same module, so I like to sort by the module. I therefore came up with this function that I call Get-Commands (I also created an alias for it).

Function Get-Commands

{

 Param($verb,

       $noun)

 Get-Command @PSBoundParameters | Sort-Object module | more

}

 

Set-Alias -Name gcms -Value get-commands

About the only thing notable here, is the use of $psBoundParameters. This cool automatic variable keeps track of parameters that are supplied to a function. I need to know if –Verb or –Noun or both –Verb and –Noun are supplied so I can create the syntax for the Get-Command cmdlet.

In the past, I would have needed to use a series of If / Else / Elseif types of construction to get the correct syntax. By using $PSBoundParameters, I do not need to do this. I simply pass whatever is supplied as arguments to the function to the command line via $PSBoundParameters. I then sort the results on the Module parameter and send the results to the More command. It works great, and saves me a lot of repetitive typing.

Removing the AD: drive

Part of the slowness in loading the Active Directory module is due to the creation of the AD: drive. I do not use this drive all the time, but I do use the Active Directory cmdlets on nearly a daily basis. So I created a function to disable creating the AD: drive. Here is the function:

Function Remove-ADDrive

{$Env:ADPS_LoadDefaultDrive = 0} 

I load it directly via my Windows PowerShell profile. If I want the AD: drive, I just comment out the line that calls the Remove-ADDrive function.

Admin or not?

The last thing I did was modify the title of my Windows PowerShell console based on if I have Admin rights. My Test-ISAdministrator function has been talked about (and copied) widely, so I am not going to repeat it here. I use it to see if I have Admin rights. If I do, I set the Windows PowerShell console title to SUPER PowerShell dude! If I do not have Admin rights, I set the title of the Windows PowerShell console to Regular PowerShell dude. The function is shown here:

Function Set-ConsoleConfig

{

 if(-not (Test-IsAdministrator))

  {$Host.ui.RawUI.WindowTitle = "Regular PowerShell dude"}

 else {$Host.ui.RawUI.WindowTitle = "SUPER PowerShell dude!"}

} #end function set-consoleconfig

The Windows PowerShell console when launched with non-elevated permissions is shown here:

Image of console

That is all there is to adding a couple of functions to my profile. Join me tomorrow when I will talk about more cool Windows PowerShell stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

PowerTip: Reload Your PowerShell Profile

$
0
0

Summary: Reload your Windows PowerShell profile without closing and reopening Windows PowerShell.

Hey, Scripting Guy! Question How can I reload my Windows PowerShell profile to test some changes I made—without closing and reopening Windows PowerShell?

Hey, Scripting Guy! Answer Use the invocation operator with the automatic $profile variable:

& $profile

Note  Depending on how you have written your profile, you may generate a large number of errors, for example, Drive already exists or Alias already exists.

 

Learn How to Configure PowerShell Memory

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, talks about how to configure Windows PowerShell memory availability for specialized applications.

Hey, Scripting Guy! Question Hey, Scripting Guy! I really need your help. We are doing something that perhaps Windows PowerShell cannot do. At least, this is the way it seems. We have a huge file share, and we are parsing through it with a series of Select-String commands to find specific types of things. We are using Get-ChildItem to obtain files for us to parse, and we have filtered it out as much as is possible. The thing is, that when I say huge, I mean really, really huge. Absolutely GINORMOUS type of huge.

Anyway, we are perfectly resigned to the fact that Windows PowerShell will take some time to go through this parsing effort, and we have obviously tested everything on mock (much smaller) data prior to turning this thing loose. The problem is that Windows PowerShell runs for an hour or so, and then it stops with a System.OutOfMemoryException error message. It is bad enough that it happens, but it is horrible that it takes so long to occur. We make changes, reboot the server, wait for another hour, and boom!—it happens again. We have spent an entire week trying to make this work, and you are our last hope. I searched the Hey, Scripting Guy! blog, but I did not find anything helpful. So now’s your chance to be a real hero.

—AP

Hey, Scripting Guy! Answer Hello AP,

Microsoft Scripting Guy, Ed Wilson, is here. Today is a great day. I got up, and fixed some nice English Breakfast tea with a bit of organic orange rind, some peppermint and spearmint leaves, a bit of crushed cinnamon stick, and a touch of lemon grass. I must say, it is a very refreshing cup of tea. Yesterday I had an awesome session with my mentee, Ashley McGlone. I am real proud of everything he has accomplished so far. So the week is going along perfectly. I am looking forward to this Thursday (August 1, 2013). We are having the Windows PowerShell User Group meeting in Charlotte, North Carolina. It will be awesome. With everything moving along smoothly, I thought I would take some time to try to catch up a bit with questions such as yours that are emailed to scripter@microsoft.com.

Configuring memory for Windows PowerShell

To configure memory resources for Windows PowerShell, you must launch Windows PowerShell with Admin rights. If you attempt to do anything on the WSMAN: drive as a normal user, you will receive the following “Access is denied” error message:

Image of error message

In addition to Admin rights, the WinRM service must be running. In Windows PowerShell 3.0 in Windows 8, this service starts on demand. Therefore, the first attempts to access the WinRM drive will result in a prompt to start the WinRM service. I use the Get-Service cmdlet to ensure that everything started properly:

PS C:\> get-service *win*

Status   Name               DisplayName

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

Running  WinDefend          Windows Defender Service

Running  WinHttpAutoProx... WinHTTP Web Proxy Auto-Discovery Se..

Running  Winmgmt            Windows Management Instrumentation

Running  WinRM              Windows Remote Management (WS-Manag..

Check and set the machine-wide setting

The first thing to do is to check and set the machine-wide memory setting. To do this, I navigate to WsMan:\Localhost\Shell in my Windows PowerShell console. I then use the Get-ChildItem cmdlet (dir is alias) to see my settings for everything. This is shown here:

PS C:\> sl WSMan:\localhost\Shell

PS WSMan:\localhost\Shell> dir

 

   WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Shell

 

Type            Name                           SourceOfValue   Value

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

System.String   AllowRemoteShellAccess                         true

System.String   IdleTimeout                                    7200000

System.String   MaxConcurrentUsers                             10

System.String   MaxShellRunTime                                2147483647

System.String   MaxProcessesPerShell                           25

System.String   MaxMemoryPerShellMB                            1024

System.String   MaxShellsPerUser                               30

Set MaxMemoryPerShellMB

To make the change, I use the Set-Item cmdlet and change the value of MaxMemoryPerShellMB from 1 GB to 2 GB. This technique is shown here:

Set-Item .\MaxMemoryPerShellMB 2048

Now I use the Up arrow and change Get-Item to Set-Item. This command and its output are shown here:

Image of command output

Note  I am already in WsMan:\LocalHost\Shell when I run the Set-Item command. If you do not want to navigate to the folder first, you can use this command:

Set-Item WSMan:\localhost\Shell\MaxMemoryPerShellMB 2048

I notice that a warning appears that states I also need to change memory settings for plug-ins. (This is true in Windows PowerShell 3.0.) Therefore, I navigate to the plug-ins directory to make those changes. But before I make any changes, I notice there are several plug-ins listed:

PS WSMan:\localhost\Plugin> dir

   WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Plugin

 

Type            Keys                                Name

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

Container       {Name=Event Forwarding Plugin}      Event Forwarding Plugin

Container       {Name=microsoft.powershell}         microsoft.powershell

Container       {Name=microsoft.powershell.workf... microsoft.powershell.workflow

Container       {Name=microsoft.powershell32}       microsoft.powershell32

Container       {Name=microsoft.windows.serverma... microsoft.windows.servermanag...

Container       {Name=WMI Provider}                 WMI Provider

The thing that is confusing is that I need to make a memory change for each plug-in endpoint configuration that I target from the client. Luckily, I happen to know that the default Windows PowerShell endpoint is Microsoft.PowerShell, and that is the only one I need to change. I type the following command:

Set-Item .\microsoft.powershell\Quotas\MaxConcurrentCommandsPerShell 2048

The command results in a warning that states I need to restart WinRM and that the value for the plug-in will only work if it is less than or equal to the value for the global memory setting. Here is the command and the output:

Image of command output

Note  I was in the Wsman:\LocalHost\Plugin directory when I ran the command to set the memory for the plug-in. If you do not want to navigate to the location, use this command instead:

Set-Item WSMan:\localhost\Plugin\Microsoft.PowerShell\Quotas\MaxMemoryPerShellMB 2048

I use the Get-Item cmdlet to ensure that the new value took. Here is the command I use:

PS WSMan:\localhost\Plugin> get-Item .\microsoft.powershell\Quotas\MaxMemoryPerShellMB

 

   WSManConfig:

Microsoft.WSMan.Management\WSMan::localhost\Plugin\microsoft.powershell\Quotas

 

Type            Name                           SourceOfValue   Value

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

System.String   MaxMemoryPerShellMB                            2048

Restart the WinRM service

Now I need to restart the WinRM service. To do this, I use the Restart-Service cmdlet. The command is shown here:

Restart-Service winrm

Just for fun, I close the Windows PowerShell console, and then reopen it. I rerun my Get-Item commands to see if anything has reverted. As indicated in the image that follows, everything is groovy.

Image of command output

AP, that is all there is to using the WSMAN drive to configure Windows PowerShell memory. Join me  tomorrow when I will talk about more cool stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

PowerTip: Use PowerShell to Retrieve List of Control Panel Items

$
0
0

Summary: See a list of items found in Control Panel.

Hey, Scripting Guy! Question How can I use Windows PowerShell to see a list of items found in Control Panel.

Hey, Scripting Guy! Answer Use the Get-ControlPanelItem cmdlet:

Get-ControlPanelItem

 

 

PowerShell Get-Command Cmdlet Returns Only One Instance

$
0
0

Summary: Microsoft Scripting Guy, Ed Wilson, shows how to configure Windows PowerShell to return more than one instance of a command.

Hey, Scripting Guy! Question Hey, Scripting Guy! I have a problem. I recently upgraded to Windows 8, and now it seems that the Get-Command cmdlet does not work properly. In the past, I have used Get-Command as a replacement for Where.exe in that it is great at finding commands I need. But now in Windows 8, the Get-Command cmdlet only returns a single instance. What gives?

—MC

Hey, Scripting Guy! Answer Hello MC,

Microsoft Scripting Guy, Ed Wilson, is here. Tomorrow we have the Windows PowerShell User Group meeting at the Charlotte, North Carolina Microsoft office. If you are in town, and do not have anything going on around 6:30 P.M., stop by. It will be loads of fun, and I can promise you will learn at least one new thing.

Using Get-Command to find commands

MC, I know it may sound strange, but I also use Get-Command to find commands. It is great at doing that. It finds Windows commands that are in my path, and it is much faster than opening Windows Explorer, and telling it to search.

For example, if I want to know if a command is available, I use Get-Command to find it for me. This is how I learned that there were two notepad.exe programs available. But when I run Get-Command in Windows 8, I am greeted with the following:

Image of command output

Hmm…Did we get rid of one of the Notepads in Windows 8? I don’t know, do I? It also makes me suspect that perhaps something is going on with Get-Command.

Force additional discovery in Get-Command

In Windows PowerShell 3.0, we made a change to Get-Command. When it finds a command, it returns. This is done for performance reasons, and results in faster searches. But if I am particularly interested in additional instances, I can force Get-Command to keep working. To do this, I specify a value for the TotalCount parameter. The value for TotalCount is the maximum value. So if I tell it to look for 10 instances of Notepad, it will keep trying. Of course, I only have two copies, so I am safe. Here is the command I use:

Get-Command notepad -TotalCount 10

The command and its associated output are shown here:

Image of command output

But where are these programs located?

To find where the programs reside, I need a bit more information. To find the additional information, I pipe the results to the Format-List cmdlet and choose all of the properties as shown here:

Get-Command notepad | Format-List *

The following image shows the command and the output associated with the command.

Image of command output

The path to the executable is in the Path property (no surprise, right?). Therefore, all I need to do is to select the path. I do this in the following command, and I can find where both Notepads reside.

PS C:\> Get-Command notepad -TotalCount 5 | Select-Object name, path

 

Name                                       Path

----                                       ----

notepad.exe                                C:\Windows\SYSTEM32\notepad.exe

notepad.exe                                C:\Windows\notepad.exe

Using the Path property

Now that I know about the Path property and the way Get-Command returns the first application it finds in the search path, I might be interested in the way the commands returns. To do this, I look at the Path variable from the $env drive. I can see that first Windows\System32 is searched, and then the Windows directory. This is shown here:

PS C:\> ($env:Path -split ';')[0..1]

C:\Windows\SYSTEM32

C:\Windows

Armed with this information I can see that the Notepad from Windows\System32 returns first (I actually saw this earlier). Therefore, the application highest in the search path returns when I do not specify TotalCount.

So, now I can use the Path property from Get-Command, and I know what it will do. So if I want to look at the byte encoding of Notepad, I can use the Get-Command cmdlet to return the path to the application. I can supply that to the Get-Content cmdlet Path parameter, and I can specify Encoding Byte. I store this in the $bytes variable, and print out the first four bytes. This is shown here:

PS C:\> $bytes = Get-Content -Path (Get-Command notepad).path -Encoding Byte

PS C:\> $bytes[0..3]

77

90

144

0

MC, that is all there is to using the Get-Command cmdlet to find commands. Join me tomorrow when I will talk about more cool Windows PowerShell stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Viewing all 3333 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>