0

I'm trying to determine which of my servers from a list (for example, servers.txt) have .NET 4.5 installed and what version of PowerShell. I have standalone commands which will tell me this on a single box -

**

**PS D:\tools> Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client'
Version       : 4.5.51641
CBS           : 1
TargetVersion : 4.0.0
Install       : 1
InstallPath   : C:\Windows\Microsoft.NET\Framework64\v4.0.30319\
Servicing     : 0
Release       : 378675
PSPath        : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework
                Setup\NDP\v4\Client
PSParentPath  : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4
PSChildName   : Client
PSDrive       : HKLM
PSProvider    : Microsoft.PowerShell.Core\Registry**

** Which shows at the top (Version) that it is indeed 4.5. Is there a way to just display the Version field and the hostname (or computername) in a table format?

Also, the same for the below command which gives you your version of PowerShell -

PS D:\tools> get-host |select-object version

Version
-------
4.0

I actually did put the full path. Here is my screen after displaying the txt file and then running the command -

PS D:\tools> type h:\servers.txt
OPP-HOLD
zOPP-SQL12HAa
zOPP-SQLESMA

PS D:\tools> Get-content -path h:\servers.txt | where {$_-match "\S"} | foreach Get-ItemProperty -ComputerName $_ 'HKLM:
\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client' -name Version
foreach : Input name "Get-ItemProperty" cannot be resolved to a method.
At line:1 char:60
+ Get-content -path h:\servers.txt | where {$_-match "\S"} | foreach Get-ItemPrope ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (OPP-HOLD:PSObject) [ForEach-Object], PSArgumentException
    + FullyQualifiedErrorId : MethodNotFound,Microsoft.PowerShell.Commands.ForEachObjectCommand

foreach : Input name "Get-ItemProperty" cannot be resolved to a method.
At line:1 char:60
+ Get-content -path h:\servers.txt | where {$_-match "\S"} | foreach Get-ItemPrope ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (zOPP-SQL12HAa:PSObject) [ForEach-Object], PSArgumentException
    + FullyQualifiedErrorId : MethodNotFound,Microsoft.PowerShell.Commands.ForEachObjectCommand

foreach : Input name "Get-ItemProperty" cannot be resolved to a method.
At line:1 char:60
+ Get-content -path h:\servers.txt | where {$_-match "\S"} | foreach Get-ItemPrope ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (zOPP-SQLESMA:PSObject) [ForEach-Object], PSArgumentException
    + FullyQualifiedErrorId : MethodNotFound,Microsoft.PowerShell.Commands.ForEachObjectCommand
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
user275373
  • 35
  • 7

2 Answers2

1

Invoke-Command is what you are asking for. The other answer is not addressing your data requests from the remote hosts.

$computers = Get-Content servers.txt

Invoke-Command -ComputerName $computers -ScriptBlock{
    $powerShellVersion = get-host | select-object -expandproperty version
    $frameWorkVersion = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Client' | select-object -expandproperty version

    New-Object psobject -Property @{
        "Computer" = $singleComputer
        "PowerShell Version" = $powerShellVersion
        "Framework Version" = $frameWorkVersion
    }
}

This untested code could be simplified, but my goal is for better understaning. For each server run the scriptblock that will return the PowerShell version and .NET version in a custom object. This should work on PowerShell 3.0. Be aware of the caveats of checking Framework version like this. If you are just looking for 4.5 this should work. You might need to add an -erroraction if 4.5 is not installed.

Community
  • 1
  • 1
Matt
  • 40,384
  • 7
  • 62
  • 97
  • 1
    This isn't as efficient as passing the computer names directly to `Invoke-Command`. If you use the `-ComputerName` parameter with multiple machines, then remote jobs are created on each machine and run in parallel. Here you are running those jobs serially. – Mike Zboray Oct 02 '14 at 18:51
  • @mikez Understood. How would you be able record the computer name in the output? The only reason I did it this way was to keep the computer name saved for output. – Matt Oct 02 '14 at 18:58
  • PowerShell should automatically attach the computer name the command was run on in the PSComputerName NoteProperty. – Mike Zboray Oct 02 '14 at 19:00
  • Thanks for the help @mikez a little more testing and I think I will have the basics down. – Matt Oct 02 '14 at 19:01
  • Thx, guys. I copied and pasted into notepad and saved to getpsinfo.ps1 but when I run it I get the following error- – user275373 Oct 03 '14 at 20:46
  • Invoke-Command : Cannot validate argument on parameter 'ComputerName'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again. At D:\tools\getpsinfo.ps1:3 char:30 + Invoke-Command -ComputerName $computers -ScriptBlock{ + ~~~~~~~~~~ + CategoryInfo : InvalidData: (:) [Invoke-Command], ParameterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.InvokeCommandCommand – user275373 Oct 03 '14 at 20:51
  • The servers.txt file just has three hostnames in it for testing. Any ideas? – user275373 Oct 03 '14 at 20:52
  • What is your output when you just run this command `Get-Content servers.txt`? You most likely need to put the full path the file in there. – Matt Oct 03 '14 at 23:22
  • Too long to put in here so I'll put it in an edit to my question above. – user275373 Oct 08 '14 at 15:09
0

Like this ?

Invoke-command -comp ( cat servers.txt ) -command { 
  get-host} | where { $_.version -eq '4.5' } | format-table *computer*, version
walid toumi
  • 1,976
  • 1
  • 9
  • 10
  • `Invoke-Command` is the right way to go however I think the OP is looking for both commands output which you dont have. Also I dont think there is a PowerShell 4.5 version – Matt Oct 02 '14 at 16:42