Adding new lines to Existing CSV using powershell? - powershell

I wrote a script that would fetch all the services running under an account name.
This part works fine except I want to add results to an existing csv. Add-content is messing up with my format. Please help as i am new here.
script:
$servers = #("a", "b")
$domain = "abc.com"
foreach($server in $servers){
$serverFQDN = $server+"."+"$domain"
Invoke-Command -computername $serverFQDN{
param($server)
Write-host "On" + $server -ForegroundColor Yellow
Get-WMIObject Win32_Service | Where-Object {$_.startname -match "ciqdev*" }
# | where-object {$_.state -eq "running"}
}-argumentlist $server | select pscomputername,caption | export-Csv Z:\RT\myCSV.csv
}

Use -Append :
export-Csv Z:\RT\myCSV.csv -Append

Related

powershell returning Get-ADComputer : The object name has bad syntax

I want to get all of the computers in a specific OU and ping them, but Im having trouble with Get-ADComputer.
code:
# Enter CSV file location
$csv = "filepath.csv"
# Add the target OU in the SearchBase parameter
$Computers = Get-ADComputer -Filter * -SearchBase "OU=Servers,DC=mydomain,DC=com" | Select Name | Sort-Object Name
$Computers = $Computers.Name
$Headers = "ComputerName,IP Address"
$Headers | Out-File -FilePath $csv -Encoding UTF8
foreach ($computer in $Computers)
{
Write-host "Pinging $Computer"
$Test = Test-Connection -ComputerName $computer -Count 1 -ErrorAction SilentlyContinue -ErrorVariable Err
if ($test -ne $null)
{
$IP = $Test.IPV4Address.IPAddressToString
$Output = "$Computer,$IP"
$Output | Out-File -FilePath $csv -Encoding UTF8 -Append
}
Else
{
$Output = "$Computer,$Err"
$output | Out-File -FilePath $csv -Encoding UTF8 -Append
}
cls
}
and im getting:
Get-ADComputer : The object name has bad syntax
At script.ps1:2 char 14
+ ... omputers = Get-ADComputer -Filter * -SearchBase "OU=Servers, ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+CategoryInfo : NotSpecified: (:) [Get-ADComputer], ADException
+FullyQualifiedErrorId : ActiveDirectoryServer:8335,Microsoft,ActiveDirectory,Management,Command.GetADComputer
ps. this code is taken from here. yes I know Im not supposed to do that but after getting this error
time after time I wanted to try a code that works.
Double check that the OU you're using as the search base is correct. This error occurs when it's off.
Apart from that, I recommend using the System.Net.NetworkInformation.Ping class. It's a lot faster than Test-Connection because you have more control over the ping timeout.
$ping = New-Object System.Net.NetworkInformation.Ping
$pingTimeutMS = 200
$computers = Get-ADComputer -Filter * -SearchBase "OU=Servers,DC=mydomain,DC=com"
$results = $computers | Sort-Object Name | ForEach-Object {
$ComputerName = $_.Name
Write-Host "Pinging $ComputerName..."
$test = $ping.Send($ComputerName, $pingTimeutMS)
[pscustomobject]#{
"Computer" = $ComputerName
"IP Address" = if ($test.Status -eq "Success") { $test.Address } else { $test.Status }
}
}
$results | Export-Csv "filepath.csv" -Delimiter ',' -NoTypeInformation -Encoding UTF8
Not appending the lines to the CSV piecemeal feels a bit less clunky, too.

Output running services to csv with computer name

I need to generate a csv containing running services to csv with the corresponding computer name
I know there is a simple way to do this and I have been tinkering with creating a new psobject, but I am not sure how to pipe the results to the new-object...
Here is what I am using:
$Input = "SomePath"
$Output = "SomeOtherPath"
$CompNames = Get-Content -Path "$Input"
ForEach ($CompName in $CompNames){
Get-Service -ComputerName $CompName | Where-Object {$_.Status -eq "Running"} | Export-csv -Path "$Output"
}
What I need in the CSV is:
ComputerName, ServiceName, DisplayName
basically, I need to add the computer name to the array.
If you want to be able to pipe the results, use a foreach-object.
$Output = "SomeOtherPath"
Get-Content -Path "SomePath" | ForEach-Object {
Get-Service -ComputerName $_ | Where-Object {$_.Status -eq "Running"} | Select-Object ComputerName, ServiceName, DisplayName
} | Export-csv -Path "$Output"
If you want to stick to a foreach statement, collect it all first then export it.
$Output = "SomeOtherPath"
$CompNames = Get-Content -Path "SomePath"
$results = ForEach ($CompName in $CompNames){
Get-Service -ComputerName $CompName | Where-Object {$_.Status -eq "Running"} | Select-Object ComputerName, ServiceName, DisplayName
}
$results | Export-csv -Path "$Output"
Try like this (Don't use $Input as variable name)
$InputX = "SomePath"
$Output = "SomeOtherPath"
$CompNames = Get-Content -Path "$Input"
ForEach ($CompName in $CompNames){
Get-Service -ComputerName $CompName | Where-Object {$_.Status -eq "Running"} | Select-Object ComputerName, ServiceName, DisplayName | Export-csv -Path "$Output"
}

PowerShell script to exclude a list of computers from getting disabled in AD

Could you guys please help me with the following scenario . Here is what i am trying to accomplish .
I generate a report of computers that need that need to be disabled in AD = file1.txt
I have a pre-made list of Computers to exclude
from getting disabled = file2.txt
I have a script to disable a list
of computers from a text file but i would like to exclude whatever
computer that exist in the file2.txt .
Here is what i have so far
$toBeDisabled = Import-CSV \\SERVER\file1.csv
$toBeExcluded = Import-CSV \SERVER\file2.csv
$toBeDisabled = $toBeExcluded | Where-Object {($toBeExcluded | Select-Object -ExpandProperty Name) -NotContains $_.Name}
ForEach ($Computer in $toBeDisabled.DeviceName)
{
$Computer = $Computer.Trim()
$ADComputer = Get-ADComputer $Computer -Properties Description
If ($ADComputer)
{
Add-Content c:\temp\computers.log -Value "The following PC $Computer has been found and disabled"
Set-ADComputer $ADComputer -Description "$($ADComputer.Description)- Disable due to inactivity - $(Get-Date) - by $env:UserName " -Enabled $False
}
Else
{ Add-Content c:\temp\computers.log -Value "$Computer not Found in Active Directory or Was disabled before"
}
}
Im getting the following error (Select-Object : Property "Name" cannot be found)
Thanks
The best approach here would be to just compare these two files first:
$toBeExcluded = Import-Csv C:\temp\file2.csv
$toBeDisabled = $toBeExcluded | Where-Object {($toBeExcluded | Select-Object -ExpandProperty Name) -NotContains $_.Name}
The above assumes that file2.csv has the same format (so it has property Name).
Then, instead of $Computers you just have to use $toBeDisabled in foreach.
I figured that out .
Compare-Object $file1 $file2 -Property "DeviceName" |
Where SideIndicator -eq "<=" |
Select DeviceName |
Export-Csv "\Server\DisableList.csv" -NoType
Thanks everyone for help

Work with ADComputer output in foreach loop

I want to output all hostnames within a network first with a foreach loop, in order (for example) to be able to ping them.
However with the following code I do not get any output in the console. The CSV file will be saved, but what is written in the loop will not be executed.
Does anyone know what the reason for this is and how I can solve it?
Import-Module activedirectory
Get-ADComputer -Filter * -Property * | Select Name | Export-CSV -Path $env:TEMP\ZZZEXPORTE.csv -NoTypeInformation -Encoding UTF8 | ForEach {
$computerName = $_.Name
Write-Host $computerName
Write-Host "----"
}
This occurs because Export-CSV does not output an object. Sometimes cmdlets like this have a -PassThru parameter which you can use to have an object passed along, but thats not the case with Export-CSV, they simply expect it to always be the last cmdlet in the pipeline.
You should instead do this:
$Computers = Get-ADComputer -Filter * -Property * | Select Name
$Computers | Export-CSV -Path $env:TEMP\ZZZEXPORTE.csv -NoTypeInformation -Encoding UTF8
$Computers | ForEach {
$computerName = $_.Name
Write-Host $computerName
Write-Host "----"
}
You could also do this:
Get-ADComputer -Filter * -Property * | Select Name | ForEach {
$computerName = $_.Name
Write-Host $computerName
Write-Host "----"
$_
} | Export-CSV -Path $env:TEMP\ZZZEXPORTE.csv -NoTypeInformation -Encoding UTF8
Noting that we have to add $_ to our ForEach-Object loop so that it outputs the current item to the pipeline, but that our Write-Host statements don't effect the pipeline because they are writing to the console only. To be honest though, this is a bit harder to follow for anyone else reading your code.

Get-hotfix on multiple computers and exporting to CSV

How do I properly use $_ in out-file? Here's my code:
get-content computers.txt |
Where {$_ -AND (Test-Connection $_ -Quiet)} |
foreach { Get-Hotfix -computername $_ } |
Select CSName,Description,HotFixID,InstalledBy,InstalledOn |
convertto-csv | out-file "C:\$_.csv"
I'm trying to execute a get-hotfix for all the computers listed in the text file then I want them to be exported to CSV with the computer name as the filename.
You need one pipeline to process the computers.txt files, and a nested one inside the foreach to process the list of hotfixes for each computer:
get-content .\computers.txt |
Where {$_ -AND (Test-Connection $_ -Quiet)} |
foreach {
Get-Hotfix -computername $_ |
Select CSName,Description,HotFixID,InstalledBy,InstalledOn |
convertto-csv | out-file "C:\$_.csv"
}
Edit: Changed computers.txt to .\computers.txt, as this is required for local paths in powershell
i can see with this:
get-content .\computers.txt | Where {$_ -AND (Test-Connection $_ -Quiet)} | foreach{ Get-Hotfix -id KB4012212 -computername $_ | Select CSName,Description,HotFixID,InstalledBy,InstalledOn | convertto-csv | out-file "C:\$_.csv" }
i can see only in which PC is the fix (KB4012212) installed.
it's possible to see the following
CSNAME Fix(Inst/NotInst)
PC1 FIxInstalled
PC2 FixNotinstalled
PC3 FixnotInstalled
..
..
etc
I monkeyed with this for a while and nothing I found on-line worked until I used this combo. 
I used the method is this thread but it was SO slow and I wanted to learn more about using jobs so this is what ended up working for me on Windows 7 PS Ver 4.
All other options were either too slow or did not return data from the remote system.
$VMs = get-content C:\WinVms.txt #Generate your hostnames list however you deem best.
foreach ($vm in $vms)
{
Write-Host "Attempting to get hotfixes on:" $vm
invoke-command -computername $vm -ScriptBlock {start-job -scriptblock {(get-hotfix | sort installedon)[-1]} | wait-job | receive-job} -AsJob
}
start-sleep 60 # give it a minute to complete
get-job | ? { $_.state -eq "Completed"} | receive-job -keep | export-csv c:\temp\win-patch.csv
you can check your failures too like this: 
get-job | ? { $_.state -eq "Failed"}