Powershell output to a text file - powershell

I am creating a script that pulls all of the date and time information from our servers. The script gets the servers from a text file. I am having is getting the output of a script to be written to a text file.
I tried using a pipe with Out-File like so:
$servers = gc "C:\Users\Public\Shell_NTP\TestList.txt"
foreach ($server in $servers){
$dt = gwmi win32_operatingsystem -computer $server
$dt_str = $dt.converttodatetime($dt.localdatetime)
write-host "$($server) current local time is $($dt_str)" | Out-File
"C:\Users\Public\Shell_NTP\TestListOutput.txt"
Then I tried the simple carrot output like so:
$servers = gc "C:\Users\Public\Shell_NTP\TestList.txt"
foreach ($server in $servers){
$dt = gwmi win32_operatingsystem -computer $server
$dt_str = $dt.converttodatetime($dt.localdatetime)
write-host "$($server) current local time is $($dt_str)" >
C:\Users\Public\Shell_NTP\TestListOutput.txt
And that did not work either. So any help or advice would be excellent.
TL;DR Trying to get the powershell output into a text file or some other more usable file format.

Don't use write-host - use write-output
write-host will only output your string to the console, the data will not be passed along the pipleline.

You don't need to use write-output you can just
"text" | Out-File ...
into a text file or some other more usable file format
CSV is a more usable format. The format you're writing is something you will have to process again to get the data back out of the text. CSV you can just Import-Csv to get it back. Or open in Excel, etc.
gc "C:\Users\Public\Shell_NTP\TestList.txt" | ForEach {
$dt = gwmi win32_operatingsystem -Computer $_
[PSCustomObject]#{
'ServerName' = $_
'DateTime' = $dt.converttodatetime($dt.localdatetime)
}
} | Export-Csv C:\Users\Public\Shell_NTP\TestListOutput.csv -NoTypeInformation

Related

How to run Powershell on a list of computers

I'm trying to run a remote command on a list of computers that available in plain text file (1 computer per line) in a file named 1.txt available under c:\1\1.txt.
What I run the powershell script the variable $comp is being run as $comp instead of being changed to the computer name
$computers = Get-Content c:\1\1.txt
foreach ($comp in $computers){
$LicenseInfo = Get-WmiObject SoftwareLicensingProduct -ComputerName $comp | Where-Object { $_.partialProductKey -and $_.ApplicationID -eq "55c92734-d682-4d71-983e-d6ec3f16059f" } | Select-Object PartialProductKey, Description, ProductKeyChannel, #{ N = "LicenseStatus"; E = { $lstat["$($_.LicenseStatus)"] } }
echo $LicenseInfo, $comp
}
run the powershell command with the Computername $comp - where $comp will be changed everytime in the loop for another name of a computer available in the c:\1\1.txt file
The reason you are getting the Select-Object error is because echo is not a command in Powershell that is for batch. Powershell uses Write-Host There is more information here:
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/write-host?view=powershell-4.0
As far as the code adding a delimiter switch to get-content will separate each computer name
Get-Content -Path c:\1\1.txt -Delimiter `r
The `r stands for a carriage return
Depending on how you want the output, you could try like this:
foreach ($comp in $computers) {
$LicenseInfo = Get-WmiObject SoftwareLicensingProduct -ComputerName $comp | Where-Object { $_.partialProductKey -and $_.ApplicationID -eq "55c92734-d682-4d71-983e-d6ec3f16059f" } | Select-Object PartialProductKey, Description, ProductKeyChannel, #{ N = "LicenseStatus"; E = { $lstat["$($_.LicenseStatus)"] } }
$LicenseInfo
$comp
}
The positional parameter error you're getting in your code is because you're giving echo variables and text, and the text isn't encapsulated in quotes.
You don't need echo or even Write-Host here if you just want to output the contents of your variables.

Need to get file info before it will be printed using PowerShell

I need to get the name and size of the file that has been sent to printer. So I need to get info about it BEFORE file is printed.
I have tried to work with files in Windows\System32\spool\PRINTERS, but I can't get any info from .SHD and .SPL files even if I pause the print work.
I started to look for some solution using Get-WmiObject -Class Win32_Printer.
Is it a correct approach? Maybe I should use some particular methods or something?
I tried this code, but it shows a mistake
$comp = $(Get-WmiObject Win32_Computersystem).Name
if ( (Get-ChildItem C:\Windows\System32\spool\PRINTERS | Measure-Object).Count -ne 0)
{
Get-WmiObject -Class win32_service -filter 'name="spooler"' -ComputerName $comp | Invoke-WmiMethod -Name StopService | out-null
$name = $(Get-WmiObject Win32_PrintJob).Document
$size = $(Get-WmiObject Win32_PrintJob).Size
$time = $(Get-WmiObject Win32_PrintJob).StartTime
"$comp,$name,$size,$time" | Out-file C:\Scripts\PrintJobs.csv -Append
Set-Service spooler -ComputerName $comp -Status Running
}
What is wrong?
PowerShell is a new thing for me and for now I'm totally lost with this task
Unless you know when to run the powershell I don't see how you can get this information "Before" the print job is sent. You would have to keep the spooler "Paused" and then when the script is run set it to Running and then pause it again until the next time the script is run.
one thing is that "Get-WmiObject Win32_PrintJob" will most likely return a collection of all current spooled jobs. so your code should look something like this to get the information you are looking for:
$comp = $(Get-WmiObject Win32_Computersystem).Name
$jobs=Get-WmiObject Win32_PrintJob
$jobInfo = $jobs | ForEach-Object {"$comp,$($_.Document),$($_.Size),$($_.StartTime)"}
$jobInfo | Out-file C:\Scripts\PrintJobs.csv -Append

Powershell Script for getting username and lastlogon/off from text file

$Inventory = Get-Content -Path "C:\Temp\computer list.txt"
foreach ($Computer in $Inventory) {
(Get-WmiObject -Class win32_process -ComputerName $Computer | Where-Object name -Match explorer).getowner().user
}
I'm trying to run a script that will get me the username and timestamp of lastlogon through a list of computer names in a text file associated with AD.
I can manage to get the names but I run into null-valued errors as it goes through the list and takes longer than expected to finish.
How would I go about fixing that and adding a timestamp for users who last logged on/off?
A better method would be to parse through event logs to find their log on log off times
this script looks like it fits the bill
https://gallery.technet.microsoft.com/scriptcenter/Find-user-logon-duration-667b8c48
you could then use it like this
$Inventory = Get-Content -Path 'C:\Temp\computerlist.txt'
ForEach ($Computer in $Inventory) {
Get-OSCUserLogonDuration -ComputerName $Computer -IncludeRemoteInteractive -
Verbose | FT -AutoSize
}

Powershell out-file and name the file

I want to automate our auditing process, where we provide the local admin members, currently this is done with screenshots. I cobbled together the below code, which prompts for a server name and create a file with the local admin members. However this requires me to rename the file.
I want to be able to input the server name and have that also be the out-file name. I'm just not seeing the tree through the forest an how I go about it. Lots of stuff for appending file names but I didn't see anything for renaming a file you create.
Thanks
function get-localadmins {
[cmdletbinding()]
Param(
[string]$computerName
)
$group = get-wmiobject win32_group -ComputerName $computerName -Filter "LocalAccount=True AND SID='S-1-5-32-544'"
$query = "GroupComponent = `"Win32_Group.Domain='$($group.domain)'`,Name='$($group.name)'`""
$list = Get-WmiObject win32_groupuser -ComputerName $computerName -Filter $query
$list | % {$_.PartComponent} | % {$_.substring($_.lastindexof("Domain=") + 7).replace("`",Name=`"", "\")}
}
$Workstation = Read-Host "Computer Name"
get-localadmins $Workstation | Out-File c:\temp\ENTERSERVERNAME_LocalAdmin.txt
Try this out
| Out-File -FilePath "C:\Temp\${Workstation}_LocalAdmin.txt" -Append

Get WMI Data From Multiple Computers and Export to CSV

So having some good old fashion Powershell frustrations today. What I need to do is this:
Get a list of computers from a file
Query those computers for "CSName" and "InstallDate" from Win32_OperatingSystem
Convert InstallDate into a useable date format.
Export all that to a .Csv
I've tried so many different iterations of my script. I run into 2 major issues. One is that I can't export and append to .Csv even with Export-Csv -Append. It just takes the first value and does nothing with the rest. The 2nd is that I can't get the datetime converter to work when piping |.
Here's a few samples of what I've tried - none of which work.
This sample simply errors a lot. Doesn't seem to carry $_ over from the WMI query in the pipe. It looks like it is trying to use data from the first pipe, but I'm not sure.
Get-Content -Path .\Computernames.txt | Foreach-Object {
gwmi Win32_OperatingSystem -ComputerName $_) |
Select-Object $_.CSName, $_.ConvertToDateTime($OS.InstallDate).ToShortDateString()
} | Export-Csv -Path Filename -Force -Append -NoTypeInformation
}
This one simply exports the first value and gives up on the rest when exporting .Csv
$Computers = Get-Content -Path .\Computernames.txt
foreach ($Computer in $Computers) {
echo $Computer
$OS = gwmi Win32_OperatingSystem -ComputerName $Computer
$OS | Select-Object
$OS.CSName,$OS.ConvertToDateTime($OS.InstallDate).ToShortDateString() |
Export-Csv -Path $Log.FullName -Append
}
This one does get the data, but when I try to select anything, I get null values, but I can echo just fine.
$OS = gwmi Win32_OperatingSystem -ComputerName $Computers
$OS | Foreach-Object {
Select-Object $_.CSName,$_.ConvertToDateTime($OS.InstallDate).ToShortDateString() |
Export-Csv -Path $Log.FullName -Force -Append -NoTypeInformation
}
This feels like it should be ridiculously simple. I can do this in C# with almost no effort, but I just can't get PS to do what I want. Any help would be much appreciated!
Here you go,
$Array = #() ## Create Array to hold the Data
$Computers = Get-Content -Path .\Computernames.txt
foreach ($Computer in $Computers)
{
$Result = "" | Select CSName,InstallDate ## Create Object to hold the data
$OS = Get-WmiObject Win32_OperatingSystem -ComputerName $Computer
$Result.CSName = $OS.CSName ## Add CSName to line1
$Result.InstallDate = $OS.ConvertToDateTime($OS.InstallDate).ToShortDateString() ## Add InstallDate to line2
$Array += $Result ## Add the data to the array
}
$Array = Export-Csv c:\file.csv -NoTypeInformation