by willbs at 2013-02-26 09:44:40
sorry about my noobnessby DonJ at 2013-02-26 12:41:05
i am trying to write a script that will check that these processes are running (or maybe even available) and then make sure that they are the right version
#$Proc = "WINWORD",
"SVCHOST",<br>"CERTSRV",
"GOOPY",<br>"OUTLOOK"
$Vers = "14.0.6129.5000",
"6.1.7600.16385 (win7_rtm.090713-1255)",
"6.1.7600.16385 (win7_rtm.090713-1255)",
"1.0.0.0",
"2.0.0.0",
if it’s easier to combine the 2 variables, i’m ok with that
this will tell me which processes are not running but i can’t figure/find out how to fold in the version check
$Data = @()
$Script = {param($Procs) if (-not (get-process $Procs -errorAction SilentlyContinue) )<br>{ "Process $Procs IS NOT running! or the version is (list incorrect version) instead of $vers" }}<br>foreach ($EXV in $Proc) {<br>$Data += invoke-command -scriptblock $Script -computername 192.168.0.102 -credential $credential -ArgumentList $EXV
-OutVariable out | out-file -filepath C:\TestReport.txt -append
}
thanks in advance
Everyone apologizes for being a "n00b." No need :).by willbs at 2013-02-26 13:25:39
$check = @{‘winword’=‘14.0.6129.5000’;‘outlook’=‘2.0.0.0’}
foreach ($item in $check) {
$ps = Get-Process -name $item.key
if ($ps.fileversion -ne $item.value) { ‘not equal’ }
}
That’s one way.
when i run that code, i get this errorby DonJ at 2013-02-26 13:32:11
Get-Process : Cannot validate argument on parameter ‘Name’. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.
At line:3 char:26
+ $ps = Get-Process -name $item.key
+ ~~~~~~~~~
+ CategoryInfo : InvalidData: ( [Get-Process], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetProcessCommand
oh, right. Duh, sorry. Sorry, just got off vacation and my head is doing PHP for some reason.by willbs at 2013-02-26 14:05:10
In the ForEach, change $check to $check.GetEnumerator() so it’ll enumerate. Should work okay then.
great! it worked fine, just one more question, if i expand the output like belowby kittH at 2013-02-26 14:08:03
$check = @{
‘winword’=‘14.0.6129.5000’;
‘outlook’=‘2.0.0.0’}
foreach ($item in $check.GetEnumerator()) {
$ps = Get-Process -name $item.key
if ($ps.fileversion -ne $item.value) {$item.key, ‘does not have the correct version number,’, $item.value, ‘expected vs’, $ps.fileversion, ‘actual’}
}
i get this output
outlook
does not have the correct version number,
2.0.0.0
expected vs
14.0.6126.5003
actual
what would be the way to get it all on one line
Change your line to the following:by DonJ at 2013-02-26 14:12:21
{"$($item.key) does not have the correct version number, $($item.value) expected vs $($ps.fileversion) actual"}
"$($item.key) does not have the correct version, expected $($item.value) vs $(ps.fileversion)"by willbs at 2013-02-26 15:56:14
Double quotation marks are required for that to work.
thanks againby DonJ at 2013-02-26 16:05:57
i wanted to start a process if it wasn’t already started and i came up with this bulldozer-ish code
$check = @{
‘winword’=‘14.0.6129.5000’;
‘outlook’=‘2.0.0.0’}
foreach ($item in $check.GetEnumerator()) {
$ps = Get-Process -name $item.key -errorAction SilentlyContinue
if ($ps -eq $null) {start-process $item.key | wait-process $item.key }
$ps = Get-Process -name $item.key -errorAction SilentlyContinue
if ($ps.fileversion -ne $item.value) {"$($item.key) does not have the correct version number, $($item.value) expected vs $($ps.fileversion) actual"}
}
what would be the more elequent way of doing this?
Try {by willbs at 2013-02-26 16:25:52
Get-Process -Name $item.key -EA Stop
} Catch {
Start-Process $item.key | wait-process $item.key
}
You’re not far off, and you’re not "wrong." I just don’t like using SilentlyContinue to suppress an error, and then checking to see if a variable is $null. It’s all too… undefined for me. But your code assumes that the process starts correctly; if that’s always the case in your situation, then it’s fine. If not, you’d need to probably put in some kind of loop to try starting it once, then spew an error if it didn’t.
i just want to be sureby DonJ at 2013-02-26 16:32:44
i use that to replace the $ps, if, and $ps lines
Just the first two - where you get the process, and then the following If. Your code still needs the second Get-Process.by willbs at 2013-02-26 16:40:12
this is what i ranby willbs at 2013-02-26 17:02:56
$check = @{
‘WINWORD’=‘14.0.6129.5000’;
‘OUTLOOK’=‘2.0.0.0’}
foreach ($item in $check.GetEnumerator()) {
$ps = Get-Process -Name $item.key -EA Stop
} Catch {
Start-Process $item.key | wait-process $item.key
}
if ($ps.fileversion -ne $item.value) {
"$($item.key) DOES NOT HAVE THE CORRECT VERSION NUMBER, $($item.value) was expected vs $($ps.fileversion), the actual value!!!" | out-file -filepath C:\TestReport.csv -append}
i got this error message
Get-Process : Cannot find a process with the name "WINWORD". Verify the process name and call the cmdlet again.
At line:6 char:7
+ $ps = Get-Process -Name $item.key -EA Stop
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (WINWORD:String) [Get-Process], ProcessCommandException
+ FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
if i manually start winword and rerun it i get this error
Catch : The term ‘Catch’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the
path is correct and try again.
At line:7 char:3
+ } Catch {
+ ~~~~~
+ CategoryInfo : ObjectNotFound: (Catch:String) , CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
this is what i’m currently running, still having issuesby DonJ at 2013-02-26 17:03:39
$check = @{
‘WINWORD’=‘14.0.6129.5000’;
‘OUTLOOK’=‘2.0.0.0’}
foreach ($item in $check.GetEnumerator()) {
Get-Process -Name $item.key -EA Stop
} Catch {
Start-Process $item.key | wait-process $item.key
}
$ps = Get-Process -name $item.key
if ($ps.fileversion -ne $item.value) {
"$($item.key) DOES NOT HAVE THE CORRECT VERSION NUMBER, $($item.value) was expected vs $($ps.fileversion), the actual value!!!" | out-file -filepath C:\TestReport.csv -append}
You missed a bit :). The Try{} part. I think you’ve also mis-balanced your braces. You gotta watch that stuff. Focus on nice formatting - don’t jam all the code together like you’re doing. Makes it harder to spot these problems. It can also help to put some comments in to help follow the logic.by willbs at 2013-02-26 17:08:29
$check = @{
‘WINWORD’=‘14.0.6129.5000’;
‘OUTLOOK’=‘2.0.0.0’}
# $item will be one item to check
foreach ($item in $check.GetEnumerator()) {
Try {
# Try to get the process
$ps = Get-Process -Name $item.key -EA Stop
} Catch {
# We got an error, so the process does not exist
# and $ps is empty. try to start the process.
Start-Process $item.key | wait-process $item.key
}
# You have to do this again, because if the process didn’t
# exist $ps will be empty right now
$ps = Get-Process -Name $item.key -EA Stop
# now that it’s running, check it
if ($ps.fileversion -ne $item.value) {
"$($item.key) DOES NOT HAVE THE CORRECT VERSION NUMBER, $($item.value) was expected vs $($ps.fileversion), the actual value!!!" | out-file -filepath C:\TestReport.csv -append
}
}
Now do me a favor - don’t just paste that and run it. Read it and make sure it all makes sense to you. If it doesn’t, PLEASE ask. I’m not here to just write the script for you - I want to help you understand why and what’s going on <grin>.
oh my god i’m so sorry, when you wrote "try" i thought you were saying try it, i didn’t know it was code, DUHby DonJ at 2013-02-26 17:15:25
i’m going to have to read up on catch and try but the rest makes sense
ya i’ll work on my formating also
talk about noob, jeez thanks for all of your help
Sp long as it helped you learn it, that’s what we’re here for.by willbs at 2013-02-27 11:33:34
i am now trying to perform the routine on a remote machine, here is a line of my code modified from aboveby DonJ at 2013-02-27 11:54:28
$ps = invoke-command -scriptblock {Get-Process -Name $item.key -errorAction Stop} -computername 192.168.0.102 -credential $credential
i get this error
Cannot validate argument on parameter ‘Name’. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.
+ CategoryInfo : InvalidData: ( [Get-Process], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetProcessCommand
+ PSComputerName : 192.168.0.102
what do i need to do with Name
That’s because $item has no meaning on the remote machine.by willbs at 2013-02-28 08:37:37
$ps = invoke-command -scriptblock {param($item) Get-Process -Name $item.key -errorAction Stop} -argumentlist $item -computername 192.168.0.102 -credential $credential
That’s how you insert a local variable into the remote script block. There’s a more attractive way in v3, but you didn’t mention which version of the shell you’re using.
i have v3 but that way works greatby DonJ at 2013-02-28 08:43:42
thanks for your help
In v3, you can just do { Get-Process -name $local:item.key -EA Stop } - the $local modifier pulls the variable from your local machine before sending it off to the remote machine.