PowerShell Beginner Intro, and Assist Request

This topic contains 0 replies, has 1 voice, and was last updated by Profile photo of Forums Archives Forums Archives 5 years, 5 months ago.

  • Author
    Posts
  • #5812

    by Shaun_Ketterman at 2013-04-17 05:04:13

    Hello Folks,

    My name, as you may have guessed, is Shaun Ketterman. I am currently serving as an IT in the US Navy, stationed in Misawa, Japan. Not too bad of a gig, friendly people, amazing food, and it feels 'clean'. On an exiting note (for me), I've got a daughter on the way who is due in a few days time, can't wait! I'm also a student at ECPI College of Technology, and I heard of powershell.org through the instructor of the class I am currently taking (Network Administrative Scripting), so I figured it would be in my extreme benefit to create an account and attempt to get my learn on. I was hoping to at least engage in some conversation prior to calling out for help, but I'm having a little more trouble with PowerShell than I thought I would. I've been racking my brain on a single assignment for the last 6 hours, and I'm frustrated to the point that I want to break my keyboard lol. Anyways, any guidance would be greatly appreciated.

    The task is to create a simple script that displays my OS, Service Pack, CPU, and free space on my C: drive. I'm fairly certain I've got the syntax down, but there are some minor issues I can't work out.

    I've tried 2 methods so far. The first, was to create a variable for each object I need (OS, CPU, etc), then add those variables as the elements in an assoiative array.

    My code for this option is (saved as shaun.ps1):

    # Create a variable for the Operating System
    $os = gwmi win32_operatingsystem | select -property name

    # Create a variable for the Service Pack
    $servicepack = gwmi win32_operatingsystem | select -property servicepackmajorversion

    # Create a variable for the CPU
    $CPU = gwmi win32_processor | select -property name

    # Create a variable for the HDD free space
    $freespace = gwmi win32_logicaldisk | where {$_.deviceid -eq "C"} | select freespace | foreach-object

    {[math]::round($_.freespace/1MB)}

    # Create an associative array with OS, Service Pack, CPU, and Free Space as keys, and the variables above as the elements
    $aa = @{"Operating System"="$os";"Service Pack"="$servicepack";"CPU"="$CPU";"HD Free Space"="$freespace"}

    When I run this script, PowerShell prompts me:

    "cmdlet ForEach-Object at command pipeline position 4
    Supply values for the following parameters:
    Process[0]:
    Process[1]:
    Process[2]:
    Process[3]:
    Process[4]:
    Process[5]:
    Process[6]:
    Process[7]:
    Process[8]:
    Process[9]:
    Process[10]:

    It only shows Process[0]: first, so I type in something, such as "OS", then is shows [1], then [2], and so on. Not being able to figure out what the issue is here, I decided to create the script by declaring another associative array, and using gwmi win32_[class]....as the keys. The giant wall of code I have for this is:

    PS C:\> $assignment=@{"OS"=gwmi win32_operatingsystem | select -property name;
    "Service Pack"=gwmi win32_operatingsystem | select -property servicepackmajorversion;
    "CPU"=gwmi win32_processor | select -property name;
    "HD Free Space"=gwmi win32_logicaldisk | where {$_.deviceid -eq "C"} | select freespace | foreach-object {[math]::round($_.freespace/1mb)} }

    When I save this variable, then run it in powershell (not saving it as a .ps1 and running it, just typing $assignment), I get the results I want, but the formatting is faulty (please see attached screen capture). The order of the items is incorrect, as I would like them to appear, from top to bottom, in the same order I add them to the array. Also, if you see the value section, there are a lot of extra characters in there, and the free space value doesn't show up.

    I'm confident that I am missing something simple here, but again, after hours and hours, I'm at my wits end. Any guidance would be greatly appreciated. Thank you in advance, and I look forward to learning as much as I can here!

    Regards,

    Shaun

    by happysysadm at 2013-04-17 05:34:49

    Hi Shaun,

    another one on board for Powershell then!!

    Look, your code is not that bad.

    You have to remove the extra newline after foreach (in fact you don't need foreach at all...) and also access WMI this way:
    [code2=powershell]# Create a variable for the Operating System
    $os = (gwmi win32_operatingsystem).name

    # Create a variable for the Service Pack
    $servicepack = (gwmi win32_operatingsystem).servicepackmajorversion

    # Create a variable for the CPU
    $CPU = (gwmi win32_processor).name

    # Create a variable for the HDD free space
    $freespace = (gwmi win32_logicaldisk | where {$_.deviceid -match "C"}).freespace/1MB

    # Create an associative array with OS, Service Pack, CPU, and Free Space as keys, and the variables above as the elements
    $aa = [ordered] @{"Operating System"="$os";"Service Pack"="$servicepack";"CPU"="$CPU";"HD Free Space"="$freespace"}[/code2]
    As you can see in the last line I used the [ordered] to sort hashtable elements in the same order you put them inside. It olny works in Powershell V3 though.

    Also I changed -eq into -match for string compare.

    his script can be improved more and more, I'll see if I can make it better for you. Meanwhile tell me if it is ok funwtionalitywise.

    Carlo

    by Shaun_Ketterman at 2013-04-17 06:02:57

    Carlo,

    Thank you immensely for the feedback. I am running PowerShell v2.0. I know I can use some form of sorting, but I think I have to put it at the end of the line. I made the other change (eq – match), so now my code looks identical to what you provided (minus Line 14 "ordered"). When I go into PowerShell and run the script, it just goes back to a PS> prompt. Maybe I am off here as well? I have the .ps1 file (shaun.ps1) saved at C:\Scripts\shaun.ps1. When I open powershell, it defaults to C:\Users\Shaun, but I've read to use the full path when running a script, so I just type C:\scripts\shaun.ps1, but it 'thinks' for a split second before going back to the PS> prompt.

    I've also downloaded the trial version of Primal Script 2012, and I can import the file there, then run the script, but the 'output' pane doesnt show anything, just "execution time 00:00:01".

    I'll thank you again for any guidance, but I need to head off to bed (it's getting late here in Japan).

    Regards,

    Shaun

    by ArtB0514 at 2013-04-17 06:14:54

    Shaun:
    You almost have it. Carlo's script saves the data in a variable ($aa). All you need to do is to either output the variable by adding a final line to the script with just $aa in it, or to remove "$aa = [ordered]" from it so that it looks like this:
    @{"Operating System"=$os;"Service Pack"=$servicepack;"CPU"=$CPU;"HD Free Space"=$freespace}
    (You can remove the quote marks from the variables in this case because they are already strings.)

    by happysysadm at 2013-04-17 06:16:41

    No problem. The result of your WMI requests is stored into the $aa variable.

    Just add $aa at the end of the script on a new line and Powershell will show you its content.

    by happysysadm at 2013-04-17 06:28:57

    Also, to sort your results the way you like in Powershell V2, your best bet is .net System.Collections.Specialized.OrderedDictionary
    [code2=powershell]$aa = New-Object System.Collections.Specialized.OrderedDictionary

    # Create a variable for the Operating System
    $os = (gwmi win32_operatingsystem).name
    $aa.Add("Operating System",$os)

    # Create a variable for the Service Pack
    $servicepack = (gwmi win32_operatingsystem).servicepackmajorversion
    $aa.Add("Service Pack",$servicepack)

    # Create a variable for the CPU
    $CPU = (gwmi win32_processor).name
    $aa.Add("CPU",$CPU)

    # Create a variable for the HDD free space
    $freespace = (gwmi win32_logicaldisk | where {$_.deviceid -match "C"}).freespace/1MB
    $aa.Add("HDD Free Space",$freespace)

    $aa[/code2]
    Otherwise you could stick to a hashtable and pipe its output to sort-object cmdlet, which allows for sorting by a specific property name, which is not what you want here.

    Last but definitively not least, learn to take advantage of bulltin help system and learn to use get-member to imrove your inside knowledge of Powershell:

    get-help sort-object
    $aa | get-member

    Carlo

    by Shaun_Ketterman at 2013-04-17 14:29:31

    All,

    You will get sick of me saying "Thank you", but thank you! And wow, the only thing I was missing was to simply show the contents of the array at the end of the script. Yikes!

    I do want to mention that I have used the get-help cmdlet extensively to this point, as well as google, youtube, etc. I think my main problem is that I don't know how to 'look' for the help. Rather, I don't yet really know 'what' I'm looking for in most cases, if that makes any sense. For instance, with this script, it didn't even occur to me that I wasn't instructing PowerShell to output the array, I just figured it wasn't doing so because I had syntax errors in my script. Ultimately, I won't ask for assistance unless I really can't figure it out, so again, many thanks to everyone here for the assistance.

    Okay, with that said, I've got everything working with 1 more slight issue – here is my output (note the formatting of the output looks fine as I'm typing it, but when I 'preview' my post, the spacing between "Name" and "Value" gets removed):

    Name Value
    —- —–
    HD Free Space 113167.86328125
    Service Pack 1
    Operating System Microsoft Windows 7 Professional |C:\Windows|\Device\Harddisk1\Partition1
    CPU Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz

    The value of my OS, as you can see, is correct, but also has all that extra information after "Professional". My code for this variable is: $os=(gwmi win32_operatingsystem).name
    I don't really want anyone to give me this answer, but just assure me that I am missing something in order for the result of my line above to NOT display that folder path in the OS line.

    Regards,

    Shaun

    by DonJ at 2013-04-17 14:55:03

    Use the Code button to format your code in the forums. It'll help preserve the formatting. HTML doesn't like to preserve spaces.

    Personally, I regard "Professional" as part of the version. I don't see a problem with having it there. Without the formatting intact (try that CODE button), I'm having a bit of a tough time following what this looks like.

    by Nobody at 2013-04-17 15:15:21

    I'd like to add a couple of things.

    First, try to avoid multiple queries to the same wmi class.

    So instead of

    # Create a variable for the Operating System
    $os = gwmi win32_operatingsystem | select -property name

    # Create a variable for the Service Pack
    $servicepack = gwmi win32_operatingsystem | select -property servicepackmajorversion

    Make a single query to the win32_operating system class and assign to a variable. Then reference the needed property values like so. It's also recommended to filter out just the properties you will be using.
    $a = get-wmiobject -class win32_operatingsystem|select-object name, servicepackmajorversion
    $a.name
    $a.servicepackmajorversion

    Now regarding your last question about the "extra" information in the OS name. If you look at all the properties of the win32_operatingsystem class, you might find that there is another property that works better for you, like say....caption


    $a = get-wmiobject -class win32_operatingsystem
    $a|fl *
    $a.caption

    by Shaun_Ketterman at 2013-04-18 01:23:35

    Thank you again, everyone.

    DonJ – I will use the code button from here on out, and I do want "Professional" to be a part of the output, just not the stuff that follows it to the right.

    Nobody – Thank you for the tip!

You must be logged in to reply to this topic.