Right now the below script imports info from a CSV file then outputs in a CSV file the computer name, expectedIP, Status, GoodIP, dnsName. This is all through custom PS object.
I am currently trying to get an output known as actual IP. I am not quite sure how to pull the IP via the ping function that pings the host name. For instance if the hostname that is being pinged check the IP and returns true or false. How could it output what the actual IP of the server is instead of outputting true or false?
Here is the script:
$compinfo = import-csv .\compinfo.csv
$lookupData = foreach ($comp in $cominfo) {
$nslkup = [System.Net.DNS]::GetHostEntry($comp.hname)
$ping = (Test-Connection -ComputerName $comp.hname -Count 1 -ErrorAction SilentlyContinue)
if ($ping) {
$status = "up"
} else {
$status = "down"
}
if ($nslkup.AddressList.IPAddressToString -eq $comp.ip) {
$ipgood = $true
} else {
$ipgood = $false
}
[PSCustomObject]#{
computerName = $comp.hname
expectedIp = $comp.ip
status = $status
goodIp = $ipgood
dnsName = $nslkup.hostname
}
}
$lookupData | Export-Csv .\lookups.csv -NoTypeInformation
I appreciate everyone that commented on this. I figured it out. Here is the correct code for anyone else that has this issue in the future.
$compinfo = import-csv .\compinfo.csv
$lookupData = foreach($comp in $compinfo)
{
$nslkup = [System.Net.DNS]::GetHostEntry($comp.hname)
$ping = (Test-Connection -ComputerName $comp.hname -Count 1 -ErrorAction SilentlyContinue)
if($ping)
{
$status = "up"
}
else
{
$status = "down"
}
if($nslkup.AddressList.IPAddressToString -eq $comp.ip)
{
$ipgood = $true
}
else
{
$ipgood = $nslkup.AddressList.IPAddressToString
}
[pscustomobject]#{
computerName = $comp.hname
expectedIp = $comp.ip
status = $status
goodIp = $ipgood
dnsName = $nslkup.hostname
}
}
$lookupData | export-csv .\lookups.csv -NoTypeInformation
Notice I replaced $False with $nslkup.AddressList.IPAddressToString
Related
Need some help adjusting this code so that it will only provide IP addresses that are not pinging and will be exported to a CSV. Currently, it outputs both up and down IP's and I want to clean up some of the clutter.
$ping = (Test-Connection -ComputerName $comp.IPAddress -Count 1 -ErrorAction SilentlyContinue)
if($ping)
{
$status = "Up"
}
else
{
$status = "Down"
}
[pscustomobject]#{
Location = $comp.Location
IP = $comp.IPAddress
Status = $status
}
I have tried manipulating the $status variable but haven't had any luck. I am sure it's something very simple, I am just missing it.
# -Quiet means we just return a boolean true / false value
$ping = Test-Connection -ComputerName ($comp.IPAddress) -Count 1 -ErrorAction SilentlyContinue -Quiet
if(-not $ping)
{
# we only care about when it's down, so move the logic to return our object here
[pscustomobject]#{
Location = $comp.Location
IP = $comp.IPAddress
Status = 'Down'
}
}
Aramus, Welcome to SO!
Test-Connection returns a Null if the connection is down so...
$ping = (Test-Connection -ComputerName $($comp.IPAddress) -Count 1 -ErrorAction SilentlyContinue)
if($Null -ne $ping)
{
$status = "Up"
}
else
{
$status = "Down"
}
Also note the $() around $Comp.IPAddress, this is to insure the parser fetches the IPAddress before running the rest of the command.
So I am trying to Purge IPs from tool that we use. Before I can purge the assets we need to make sure the host is not pingable and not in DNS. I am new to PS and cant seem to wrap my head around on doing this. Any help is greatly appreciated. I have been doing this as a manual process by pinging the list of IPs and hostnames and doing a nslookup in cmd prompt before selecting the IPs that are needing to be removed. I have about 13k IPs left to do.
Update:
I want to implement this portion into it. Where In cell A it will have the IP
cell B will let me know if it is up or down. And Cell D will let me know if it is DNS aswell. Below is the script I got for pinging and checking if up or down and checking AD to see if the hostname is still in AD. I want it similar to this.. Please excuse my english
$path = ".\results.xls"
$objExcel = new-object -comobject excel.application
if (Test-Path $path)
{
$objWorkbook = $objExcel.WorkBooks.Open($path)
$objWorksheet = $objWorkbook.Worksheets.Item(1)
}
else {
$objWorkbook = $objExcel.Workbooks.Add()
$objWorksheet = $objWorkbook.Worksheets.Item(1)
}
$objExcel.Visible = $True
#########Add Header####
$objWorksheet.Cells.Item(1, 1) = "HostName"
$objWorksheet.Cells.Item(1, 2) = "Result"
$objWorksheet.Cells.Item(1, 3) = "MachineIP"
$objWorksheet.Cells.Item(1, 4) = "Active Directory"
$machines = Get-Content .\machinelist.txt
$row=2
$machines | foreach-object{
$ping = $null
$iname = $null
$machine = $_
$ping = Test-Connection $machine -Count 1 -ea silentlycontinue
$checkAD = try {$comp = Get-ADComputer -Identity $machine -ErrorAction
Stop
if ($comp){"Yes"}else{throw}
}
catch {"No"}
$objWorksheet.Cells.Item($row,4) = $checkAD
if($ping){
$objWorksheet.Cells.Item($row,1) = $machine
$objWorksheet.Cells.Item($row,2) = "UP"
$iname = $ping.IPV4Address.IPAddressToString
$objWorksheet.Cells.Item($row,3) = $iname
$row++}
else {
$objWorksheet.Cells.Item($row,1) = $machine
$objWorksheet.Cells.Item($row,2) = "DOWN"
$row++}
}
Here's a start, using Test-Connection and Resolve-DnsName, assuming you have a list of hosts' IP and name separated by a space, with a carriage return between each host:
$Assets = #"
127.0.0.1 localhost
255.255.255.255 fakehost
"#
$FailedPing = #()
$NoDNS = #()
$Assets -split "`r" | %{
$ipaddress = ($_.split(' ')[0]).trim()
$hostName = ($_.split(' ')[1]).trim()
Write-Host "IP: $ipaddress HOST: $hostName "
Try {
Test-Connection -ComputerName $ipaddress -Count 2 -ErrorAction Stop | Out-Null
}Catch {
$FailedPing += [pscustomobject]#{IP=$ipaddress; HostName = $hostName}
}
Try {
Resolve-DnsName -Name $hostName -ErrorAction Stop | Out-Null
}Catch {
$NoDNS += [pscustomobject]#{HostName = $hostName;Problem = $Error[0].Exception}
}
}
$FailedPing | ft
$NoDNS | ft
I have a basic script, which will shutdown Windows services and generate a report about their shutdown processes. I also want to include two more columns into my output variable ($table), which will be timestamp values i.e. when shutdown tasks were launched and when they finished. I have no idea how to implement this into my report.
$processlist = #('SQLTELEMETRY$TESTDB', 'MSSQL$TESTDB', 'SQLWRITER')
$get = ''
$table = #{ }
$failed = 0
foreach ($proc in $processlist) {
stop-service -name $proc -force
}
#start-sleep -s 120
foreach ($proc in $processlist) {
$get = get-service $proc -Erroraction ignore
if ($get.Status -eq 'Running') {
$table += #{$proc = 'Running' }
}
else {
$table += #{$proc = 'Stopped' }
}
}
foreach ($value in $table.GetEnumerator()) {
if ($value.Value -eq 'Running') {
$failed += 1
}
}
if ($failed -gt 0) {
$err = 'FAILED'
}
else {
$err = 'SUCCESS'
}
$table.GetEnumerator() | Select-Object -Property Name, Value | export-csv appreport.csv -delimiter ";" -force -notypeinformation
(HTML part here...)
Instead of adding stuff into a Hashtable, I think it would be a lot easier to build an array of objects and write that as CSV file.
Something like this:
$serviceList = 'SQLTELEMETRY$TESTDB', 'MSSQL$TESTDB', 'SQLWRITER'
$maxAttempts = 10
# $result will become an array of PsCustomObjects you can easily pipe to Export-Csv
$result = foreach ($service in $serviceList) {
$shutStart = Get-Date
$svc = Get-Service -Name $service -ErrorAction SilentlyContinue
if ($svc) {
for ($attempt = 0; $attempt -lt $maxAttempts; $attempt++) {
$shutResult = 'Failed'
Start-Sleep -Milliseconds 100
$svc | Stop-Service -Force -ErrorAction SilentlyContinue
# test if the service has stopped. If so exit the loop
if (($svc | Get-Service).Status -eq 'Stopped') {
$shutResult = 'Success'
break
}
}
[PsCustomObject]#{
'ServiceName' = $svc.Name
'ServiceDisplayName' = $svc.DisplayName
'ShutDownStart' = $shutStart
'ShutDownEnd' = Get-Date
'Result' = $shutResult
}
}
else {
[PsCustomObject]#{
'ServiceName' = $service
'ServiceDisplayName' = ''
'ShutDownStart' = $shutStart
'ShutDownEnd' = Get-Date
'Result' = "Failed: Service '$service' could not be found."
}
}
}
# output on screen
$result
# output to CSV
$result | Export-Csv 'D:\appreport.csv' -Delimiter ";" -Force -NoTypeInformation
The output on screen will look like this:
ServiceName : SQLTELEMETRY$TESTDB
ServiceDisplayName :
ShutDownStart : 22-8-2019 16:47:40
ShutDownEnd : 22-8-2019 16:47:40
Result : Failed: Service 'SQLTELEMETRY$TESTDB' could not be found.
ServiceName : MSSQL$TESTDB
ServiceDisplayName :
ShutDownStart : 22-8-2019 16:47:40
ShutDownEnd : 22-8-2019 16:47:40
Result : Failed: Service 'MSSQL$TESTDB' could not be found.
ServiceName : SQLWRITER
ServiceDisplayName : SQL Server VSS Writer
ShutDownStart : 22-8-2019 16:47:38
ShutDownEnd : 22-8-2019 16:47:39
Result : Success
Hope that helps
I don't really know when you want to capture the time stamp for the services, but I suggest you take advantage of the below property and add it in the loop where you think its suitable.
(Get-Process -Name $proc).StartTime
Also you can use the below properties :
UserProcessorTime
TotalProcessTime
ExitTime
I hope this will help you to capture to time.
I need a script to change the IP address on all Windows 7 pro X64 PC.
If the first 2 match 192.168 then change
If IP already change then ignore and move onto next ip/PC.
Some PC will have more then 1 port.
I have try this which works but when you run it next time it keep adding the ip address.
$site = #{
Site1 = 2;
site2 = 3;
}
$site = $site.Values
$oldRange = "192.168."
foreach ($s in $site) {
$ipAddress = $oldRange + $s + ".*"
$printer = wmic path win32_tcpipprinterport get hostaddress
$printer = $printer.Split('',[System.StringSplitOptions]::RemoveEmptyEntries)
if ($printer) {
foreach ($p in $printer) {
$OldIP = $p
$OldIP2 = $OldIP -replace $oldRange, ""
$old = [bool]($OldIP -as [IPAddress])
if ($old) {
$NewIP = "172.15.$OldIP2"
$NewIP
wmic path win32_tcpipprinterport where "hostaddress = '$OldIP'" set hostaddress="$NewIP"
}
}
} else {
Write-Host "None Found"
}
}
This is what I have done.
if anyone has better solution then please let me know
Clear-Host
$site = #{
Site1=2;
Site2=3;
}
$site =$site.Values
$oldRange = "172.11."
foreach($s in $site)
{
$printer = wmic path win32_tcpipprinterport get hostaddress
$printer=$printer.Split('',[System.StringSplitOptions]::RemoveEmptyEntries)
if($printer)
{
foreach ($p in $printer)
{
$OldIP = $p
$OldIP2 = $OldIP -replace $oldRange, ""
$old = [bool]($OldIP -as [IPAddress])
if($old)
{
$sep = $OldIP.lastindexof(".")
$network = $OldIP.substring(0,$sep)
if("10.11."+$s -ne $network)
{
$NewIP = "10.11.$OldIP2"
$NewIP
wmic path win32_tcpipprinterport where "hostaddress = '$OldIP'" set hostaddress="$NewIP"
}else{
Write-Host "IP Already Changed"
}
}else
{
Write-Host "Not a IP address"
}
}
}else{
Write-Host "None Found"
}
}
This only prints the last server in the list, I'm looking to get all servers and print to screen
$machines = (Get-BrokerMachine -AdminAddress $adminaddress -DesktopGroupName $deliverygroup | Select-Object DNSname).DNSname
foreach($machine in $machines){
$machinelist = Get-BrokerMachine -HostedMachineName $machine
if($machinelist.InMaintenanceMode -eq $true){
$status = "$machine is in maintenance mode"
}else {
$status = "$machine is not in maintenance mode"
}
}
Write-Host $status
Here is a more PowerShell-like approach (not tested):
Get-BrokerMachine -AdminAddress $adminaddress -DesktopGroupName $deliverygroup | ForEach-Object {
$machineName = $_.DNSName
[PSCustomObject] #{
"MachineName" = $machineName
"MaintenanceMode" = (Get-BrokerMachine -HostedMachineName $machine).InMaintenanceMode
}
} | Export-Csv "C:\whatever\results.csv" -NoTypeInformation
$Status is constantly being overwritten by the current machine in your list.
You're looking for:
$Status+=
As opposed to:
$Status=
You'll also want to explicitly state that $Status will be an array at the beginning like so:
$Status=#()
Or when you create the variable and omit the line at the beginning.
[array]$Status +=
Otherwise, you'll get results that run together as it will be treated as a [String]
another funky mode :
function get-BrokerMachineMode
{
param (
[Parameter(Mandatory = $true)]
[string[]]$machines
)
begin
{
$ErrorActionPreference = 'Stop'
Add-Type -Language CSharp #"
public class BrokenBroker {
qpublic System.String MachineName;
public System.String MaintenanceMode;
public BrokenBroker (string MachineName, string MaintenanceMode)
{
this.MachineName = MachineName;
this.MaintenanceMode = IsInMaintenanceMode;
}
}
"#
$status = #()
Write-Verbose "Created objects..."
}
process
{
try
{
$machines = (Get-BrokerMachine -AdminAddress $adminaddress `
-DesktopGroupName $deliverygroup | Select-Object DNSname).DNSname
foreach ($machine in $machines)
{
Write-Verbose "Checking machine: $machine"
$machinelist = Get-BrokerMachine -HostedMachineName $machine
if ($machinelist.InMaintenanceMode -eq $true)
{
$status += New-Object BrokenBroker($machine, $true)
}
else
{
$status += New-Object BrokenBroker($machine, $false)
}
}
}
catch
{
Write-Error $error[0].Exception.Message
}
$status
}
end
{
Write-Verbose "Done"
}
}
this is a function you just must to load then you can launch it just by using this command:
$computers = get-content = {PATH TO TXT FILE}
$list = get-BrokerMachineMode -machines $computers -Verbose