Missing Something

by Shaun_Ketterman at 2013-04-23 22:40:43

Hello All,


** Editing my original post **

I am creating a script which prompts the user to enter the name of a PC. If the name entered is a given value, the script needs to call 2 different functions which will 1)display a list of installed software + vendor, and 2)show free disk space and the percentage of used space on the hard drive (C:). I’m confident that I have the functions created properly, and I’m fairly certain my if/then statement is good, but they don’t work too well together to put it bluntly. Please have a look at my code so far:

# Create function to list software and vendor on workstation
# Also display freespace and percentage of used space on HDD

# Create PCname-input request
$pc=Read-Host -Prompt "Please enter the name of the PC:"

# Define function
function apps {
param ($Name=(gwmi win32_product).name,
$Vendor=(gwmi win32_product).vendor
)}

# Define HDD function
function hdd {
param ($free=(gwmi win32_logicaldisk | where {$.deviceid -match "C"}).freespace/1MB)
} # Prior to ending this function, I also need to add a parameter for percentage of used space, don’t know how to do this yet so I omitted it)

# Create if statement
if ($pc="Shaun-PC") {
apps, hdd
}
else
{
Write-Host "PC not found. Please try again."
}



I’m not sure how to include the line numbers on the forums here, but when I run this, I get an error on the line inside the if statement where I’m telling the script to call "apps, hdd". I’ve tried parenthesis, no comma, etc, but it won’t run when I put both functions there. If I use only ONE of the functions, the program runs but I get no output, just the time it took it to run (using primalscript).

As always, any guidance is greatly appreciated!


Shaun
by happysysadm at 2013-04-24 01:38:40
Hi,

you have to know that the equal sign ‘=’ is an assignement operator in Powershell.

There are different ways to compare text strings, such as:
[code2=powershell]$pc ='Shaun-PC'

$pc.CompareTo('Shaun-PC')
0

$pc -match 'Shaun-PC'
True

$pc -match 'Shaun-P'
True

$pc -match 'haun-P'
True

$pc -eq 'haun-P'
False

$pc -eq 'Shaun-PC'
True[/code2]
The first comparison returns 0 for True and 1 for False. The others comparison operators directly return Tue of False.

There also are errors in the way you call these functions, two on the same line with a comma in between. Put a function per line and pass $pc as an argument.

The WMI requests are not parameters.

When using Read-Host dont put the colon. This cmdlets does it for you.

heres’ a first draft for your script:
[code2=powershell]# Define function
function apps {
(gwmi win32_product -computername $computername).name
(gwmi win32_product -computername $computername).vendor
}

# Define HDD function
function hdd {
(gwmi win32_logicaldisk -computername $computername | where { $
.deviceid -match "C" }).freespace/1MB
}

# Create PCname-input request
$computername=Read-Host "Please enter the name of a PC"

# Create if statement
if ($computername -eq 'Shaun-PC')
{
apps $computername
hdd $computername
}
else
{
Write-Host "PC $computername was not found. Please try again."
}[/code2]
You now just have to better handle the output by inserting it in a reusable object. There are many example in this forum, I’ll let you check for it.
Do not hesitate to ask if you have any question,
Carlo
by Shaun_Ketterman at 2013-04-24 17:52:42
Thank you again, Carlo. See, my textbook really does a lousy job of demonstrating how this is done, at least in the chapters I had to read so far.

So when you want a function to be called based on user input, you have to include whatever variable that is assigned to the user input in the function as part of each argument? Which means that the gwmi command will get the information of whatever that PC name is? So even though I am writing this script for a single workstation (my own personal one), I could increase the scope to a small network if I wanted to, and the functions would call whatever information is on the PC in the $computername variable? Forgive me if that makes zero sense, I’m just trying to take all of this in. In any case, thank you again for the assist. I’m going to revisit my script to get it up and running correctly.


Shaun
by Shaun_Ketterman at 2013-04-24 18:38:05
When I take function app from above, and paste it into powershell, I went ahead and ran it by itself. I then just typed apps by itself, but I didnt get any output (the variable $computername was empty…so it errored). So I retyped up the apps function, and put my PC name in place of the $computername variable. Now it runs, but there is still no output. Next I specified:

apps | out-file C:\scripts\test.txt

The specified file was created, but it was empty. You mentioned inserting the output into a reusable object…are you referring to the output of the entire script? I wasn’t able to get any output from it, even when piped to a file (nothing on screen either). Much thanks,


Shaun
by ArtB0514 at 2013-04-25 05:59:08
Here’s a little bit more complicated a version of the Apps function that does work. I’ve added a parameter for ComputerName that defaults to the current name and then calls Get-WmiObject only once for the machine and then does a foreach against the returned values and returns an array of the name and vendor for each application found. This should work perfectly well under any version of PowerShell. The ability to use a construct like (SomeArray).name doesn’t work before version 3.0
function apps {
Param ($ComputerName = '.')
Get-WmiObject -ComputerName $ComputerName -Class Win32_Product | foreach {
New-Object PSObject -Property @{
'Name' = $.Name
'Vendor' = $
.Vendor
}
}
}


Oh, and you should use Export-Csv with the results of this version of the function.
by Shaun_Ketterman at 2013-04-25 14:38:39
Art,

That would explain why it wouldnt work for me, as I’m using v2.0 (I have to for class). The one you provided is quite a bit more complicated (I wouldnt have thought of it for sure), but I can easily see what you did. Even though it’s a little above my experience level, I’m sure this will come in handy. Many thanks to you!

Shaun
by Lery at 2013-04-25 17:50:32
I’m just browsing through this thread trying to pick things up and I noticed something that I thought would warrant mentioning. I noticed you’re querying the Win32_Product. A few weeks back I was looking at doing this and ran across a few articles warning against querying this class due to a Microsoft issue. Sure enough, I’m able to reproduce it. Here is the Microsoft support article http://support.microsoft.com/kb/974524 I’ve reproduced this on Windows Server 2008 R2.

Good luck with your script and best wishes.
by Shaun_Ketterman at 2013-04-26 19:45:37
Lery,

Thank you for the heads up. Actually, this script is for a class I’m taking, so it’s not running on my machine on a regular basis. Thankfully I’m not showing any symptoms at this point, but I will keep an eye out.


Shaun