Need to add If (Test-Connection) cmdlet - ping

Is it possible to add the If (Test-Connection) cmdlet to this script? I want to ping the host first
the run the script if the host its on.
`enter code here`
$sb = { write-host "$env:computername"
Get-ChildItem HKLM:\SOFTWARE\McAfee\AVSolution\DS\ -Recurse | ForEach-Object {
Get-ItemProperty $_.pspath
}
}
$Results = Invoke-Command -ScriptBlock $sb -ComputerName (Get-Content -Path 'C:\computers.txt')
#Show output to screen
Write-Output $Results
$Results | Export-Csv -Path 'C:\computers.CSV' -NoTypeInformation -Append

Related

Using PowerShell to verify that a specific service exists from a .txt list of server names

I am trying to verify that a specific service exists from a .txt list of server names and then output to a file. In this case I need to also add credentials so I need to use the Invoke-Command. What am I doing wrong here?
clear
start-transcript -path .\Log.txt
$servers = Get-Content .\Resources\Lab.txt
$cred = get-credential domain\Username
$name = Read-Host -Prompt 'Input your service name'
function Getinfo() {foreach($server in $servers)
{
Get-Service | Where-Object { $_.Name -eq $name}-and {$_.Status -eq "Running"}| Format-Table -AutoSize
}
}
Invoke-Command -credential $cred -ComputerName $servers -ScriptBlock ${function:Getinfo}
Stop-Transcript
I think you mean this?
$servers = Get-Content .\Resources\Lab.txt
$cred = Get-Credential domain\Username
$name = Read-Host -Prompt 'Input your service name'
Invoke-Command -Credential $cred -ComputerName $servers -ScriptBlock {
param($name)
Get-Service | Where-Object { $_.Name -eq $name -and $_.Status -eq "Running"}
} -ArgumentList $name | Format-Table -AutoSize

Exporting a computer list with OS version and up/down pings

I'm writing a script in PowerShell-ISE that allows me to ping a computer list and exports the pings associated with each computer as well as the OS version into a CSV. Below is what I got so far. I'm not exactly sure where to put the Test-Connection in here.
$good = "C:\Users\1521599002A\Desktop\good.csv"
$bad = "C:\Users\1521599002A\Desktop\bad.csv"
$Computers = Import-Csv -Path "C:\Users\1521599002A\Desktop\complist.txt" -Header "Name"
foreach ($Computer in $Computers) {
try {
Get-ADComputer -Identity $Computer.Name -Properties Name, operatingSystem |
Select Name, operatingSystem
Out-File -FilePath $good -InputObject "$Computer" -Append -Force
} catch {
$Computer.Name + " not in AD"
Out-File -FilePath $bad -InputObject "$Computer" -Append -Force
}
}

try-catch bypassing a step

I have a script that tests connection to a list of servers, and if contactable, gets the status of a service, and puts the results into three variables, $Computer, $Ping (True/False), and $Service (Running or Stopped).
The output is in a hashtable but I can only get to show the servers that ARE contactable, and not the ones that cannot be contactable.
I have placed a try/catch in the $Ping block, as well as -ErrorAction Stop, so that it doesn't attempt to run the $Service script, and instead go to the next $Computer in the array. I think I am trying to do two things at once that are conflicting each other:
add the variables to the #Splat and
don't process any further.
There are actually many more remote registry queries in my script, which will be irrelevant if the $Computer cannot be contactable, but I have shortened it for this post.
Function Get-Ping {
$Servers = (gc "c:\temp\test.txt")
foreach ($Computer in $Servers) {
Write-Host
Write-Host "---------------------------------"
Write-Host "QUERYING $Computer"
Write-Host
Write-Host "Performing ping test..."
try {
$Ping = Test-Connection $Computer -Count 1 -ErrorAction Stop
} catch {
Write-Warning "Cannot Ping $Computer"
Write-Host "Trying next computer..."
Write-Host
continue
}
if ($Ping) {$Ping="$True"}
Write-Host $Computer "can be pinged"
$svcRRStopped = $false
if ($Computer -ne $env:COMPUTERNAME) {
Write-Host "Check RemoteRegistry status..."
}
$svcRR = Get-Service -ComputerName $Computer -Include RemoteRegistry
$SelectSplat = #{
Property = (
'Computer',
'Ping',
'Service'
)}
New-Object -TypeName PSObject -Property #{
Computer=$Computer
Ping=$Ping
Service=$svcRR.status
} | Select-Object #SelectSplat
}
}
$results = Get-Ping
$tableFragment = $results | Select 'Computer','Ping','Service'
$tableFragment
Don't make things more complicated than they need to be.
function Get-Ping {
Get-Content 'C:\temp\test.txt' | ForEach-Object {
$isAvailable = [bool](Test-Connection $_ -Count 1 -EA SilentlyContinue)
if ($isAvailable) {
$rreg = Get-Service -Computer $_ -Name RemoteRegistry |
Select-Object -Expand Status
} else {
$rreg = 'n/a'
}
New-Object -Type PSObject -Property #{
Computer = $_
Ping = $isAvailable
Service = $rreg
}
}
}
Get-Ping
You can simply use the -Quiet Parameter:
Test-Connection $_ -Count 1 -Quiet

Powershell Export to CSV with three coumns

function getServerInfo
{
$serverList = Get-Content -Path "C:\Users\username\Desktop\list.txt"
$cred = Get-Credential -Credential "username"
foreach($server in $serverList)
{
$osVersion = gwmi win32_operatingSystem -ComputerName $server -ErrorAction SilentlyContinue
if($osVersion -eq $null)
{
$osVersion = "cannot find osversion"
}
$psv = Invoke-Command -ComputerName $server -ScriptBlock {$PSVersionTable.PSVersion.Major} -ErrorAction Ignore
if($psv -eq $null)
{
$psv2 = Invoke-Command -ComputerName $server -Credential $cred -ScriptBlock {$PSVersionTable.PSVersion.Major} -ErrorAction Ignore
Write "$server has $($osVersion.Caption)and PSVersion is $psv2"
}
else{
Write "$server has $($osVersion.Caption)and PSVersion is $psv"
}
}
}
I am trying to create a csv file with 3 columns.
First column will have $server, second column will have $osVersion and third will have $psv. Please help. thank you!
Rather than using the foreach loop, consider using the ForEach-Object cmdlet so that the results can be piped to other commands. Inside of the ForEach-Object script block, you can calculate the 3 values you need, and then its easy to create CSV string using string interpolation. The results can then be piped to the appropriate output file.
Get-Content -Path C:\Users\username\Desktop\list.txt | ForEach-Object {
$Server = $_
$OSVersion = gwmi Win32_OperatingSystem -ComputerName $Server -ErrorAction SilentlyContinue
$PSVersion = Invoke-Command -ComputerName $Server -ScriptBlock { $PSVersionTable.PSVersion.Major }
"$Server,$OSVersion,$PSVersion"
} | Out-File outputFilename.csv
To export to a CSV using the Export-CSV cmdlet, PowerShell expects an array of objects with the same set of properties to output. For your case you can do that fairly simply as such:
$cred = Get-Credential -Credential "username"
$AllServers=foreach($server in $serverList)
{
[PSCustomObject]#{
'Server' = $Server
'osVersion' = gwmi win32_operatingSystem -ComputerName $server -ErrorAction SilentlyContinue | Select -Expand Caption
'psv' = Invoke-Command -ComputerName $server -ScriptBlock {$PSVersionTable.PSVersion.Major} -ErrorAction Ignore -Credential $cred
}
}
$AllServers | Export-Csv c:\path\to\output.csv -notype

Issue in export Array to CSV file

I have list of machine in text file and I am trying to get the details of physical drives, OS architecture and physical memory. With the help of Matt (SO user) here is the powershell script.
$server = Get-Content .\Server.txt
#$infoObject11 = #{}
$infoObject11 = #{}
foreach ($server in $servers) {
# Gather all wmi drives query at once
$alldisksInfo = Get-WmiObject -Query "SELECT * FROM Win32_DiskDrive" -ComputerName $server -ErrorAction SilentlyContinue | Group-Object __Server
# Figure out the maximum number of disks
$MaximumDrives = $alldisksInfo | Measure-Object -Property Count -Maximum | Select-Object -ExpandProperty Maximum
# Build the objects, making empty properties for the drives that dont exist for each server where need be.
$server | ForEach-Object {
# Clean the hashtable
$infoObject1 = #{}
# Populate Server
$infoObject1.Server = $server
$HOSTNAME = Get-WMIObject -Query "Select * from Win32_OperatingSystem" -ComputerName $infoObject1.Server
# Add other simple properties here
$infoObject1.PhysicalMemory = (Get-WmiObject Win32_PhysicalMemory -ComputerName $infoObject1.Server | Measure-Object Capacity -Sum).Sum/1gb
$infoObject1.OSarchitecture =$HOSTNAME.osarchitecture
# Add the disks information from the $diskInfo Array
$serverDisksWMI = $alldisksInfo | Where-Object{$_.Name -eq $infoObject1.Server} | Select-Object -ExpandProperty Group
for ($diskIndex =0; $diskIndex -lt $MaximumDrives;$diskIndex++) {
$infoObject1."PhysicalDisk$diskIndex" = [Math]::Round(($serverDisksWMI | Where-Object{($_.DeviceID -replace "^\D*") -eq $diskIndex} | Select -Expand Size)/1GB)
}
}
# Create the custom object now.
New-Object -TypeName psobject -Property $infoObject1 | Export-Csv -path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation
}
Problem is in the CSV file I am getting single machine details but in server.txt file there are more than 1 machine. If I print $infoObject1 before New-Object then I can see there are details of multiple machine. It seems like some issue with array and I am not able to export it in CSV.
Can anybody please suggest on this.
It looks like you are having issues integrating my code. You have added a second loop that should not be there. Also as other users pointed out you are not creating the per server object outside the loop. The answer, from where your code comes from, has that part correct. I had even showed you where to put the Export-CSV.
$servers = Get-Content .\Server.txt
# Gather all wmi drives query at once
$alldisksInfo = Get-WmiObject -Query "SELECT * FROM Win32_DiskDrive" -ComputerName $servers -ErrorAction SilentlyContinue | Group-Object __Server
# Figure out the maximum number of disks
$MaximumDrives = $alldisksInfo | Measure-Object -Property Count -Maximum | Select-Object -ExpandProperty Maximum
# Build the objects, making empty properties for the drives that dont exist for each server where need be.
$servers | ForEach-Object {
# Clean the hashtable
$infoObject1 = #{}
# Populate Server
$infoObject1.Server = $_
# Add other simple properties here
$infoObject1.PhysicalMemory = (Get-WmiObject Win32_PhysicalMemory -ComputerName $infoObject1.Server | Measure-Object Capacity -Sum | Select-Object -ExpandProperty Sum)/1GB
$infoObject1.OSarchitecture = Get-WMIObject -Query "Select * from Win32_OperatingSystem" -ComputerName $infoObject1.Server | Select-Object -ExpandProperty OSArchitecture
# Add the disks information from the $diskInfo Array
$serverDisksWMI = $alldisksInfo | Where-Object{$_.Name -eq $infoObject1.Server} | Select-Object -ExpandProperty Group
for ($diskIndex =0; $diskIndex -lt $MaximumDrives;$diskIndex++) {
$infoObject1."PhysicalDisk$diskIndex" = [Math]::Round(($serverDisksWMI | Where-Object{($_.DeviceID -replace "^\D*") -eq $diskIndex} | Select-Object -ExpandProperty Size)/1GB)
}
# Create the custom object now for this pass in the loop.
New-Object -TypeName psobject -Property $infoObject1
} | Export-Csv -path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation
foreach ($server in $servers) {
...
New-Object -TypeName PSObject -Property $infoObject1 |
Export-Csv -Path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation
}
You're exporting inside the loop without using the parameter -Append (available in PowerShell v3 and newer). That overwrites your output file with each iteration, leaving you with just the data of the last server.
Either use the parameter -Append (if you have PowerShell v3 or newer):
foreach ($server in $servers) {
...
New-Object -TypeName PSObject -Property $infoObject1 |
Export-Csv -Append -Path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation
}
or move Export-Csv outside the loop (works with all PowerShell versions):
(foreach ($server in $servers) {
...
New-Object -TypeName PSObject -Property $infoObject1
}) | Export-Csv -Path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation
Note that you need to run the loop in parentheses for this to work, as foreach loops don't output to the pipeline.
You could also replace the foreach loop with ForEach-Object if you want to feed the pipeline directly:
Get-Content .\Server.txt | ForEach-Object {
$server = $_
...
New-Object -TypeName PSObject -Property $infoObject1
} | Export-Csv -Path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation