the first line output nothing in powershell - powershell

i try output parameter value in PowerShell, but it output nothing for the first time.
i have to try multiple times and it always succeeds after the first output.
does anyone know the problem?
here is the code test.ps1:
Get-Content D:/Config.txt | Foreach-Object{
$var = $_.Split('=')
New-Variable -Name $var[0] -Value $var[1]
}
Write-Host $DeskTopPath -BackgroundColor black
Write-Host $DeskTopPath -BackgroundColor green
Write-Host $DeskTopPath -BackgroundColor blue
Config.txt
DeskTopPath=D:\Users\Test\Desktop
my output
D:\Users\Test\Desktop
D:\Users\Test\Desktop
my PowerShell version: 5.1.14393.3471

Write-Host writes to the console immediately. It doesn’t wait for or care about what the pipeline is processing. It is simply executing too fast before your variable is created. You either need to add a sleep or delay or don’t use Write-Host.
Get-Content D:/Config.txt | Foreach-Object{
$var = $_.Split('=')
New-Variable -Name $var[0] -Value $var[1]
}
Start-Sleep -m 200
Write-Host $DeskTopPath -BackgroundColor black
Write-Host $DeskTopPath -BackgroundColor green
Write-Host $DeskTopPath -BackgroundColor blue
This isn't reproducible for everyone because of the number of variables involved in running PowerShell code. It will have to be trial and error.

Related

powershell catch export to csv not working

I'm writing a script that is fed a .csv and tries to make an operation and then catches into a seperate .csv but for some reason I cant seem to feed the catch info into the csv. I get the error, "Export-csv : Cannot process argument because the value of argument "name" is not valid. Change the value of the "name" argument and run the operation again."
I appreciate any input from the brains.
#imports a csv and does somthing with the data. The columns in the csv are specified by the $($_.'columnName')
Import-Csv -Path 'PathToMyCSV.csv' | ForEach-Object{
#Print associated User
Write-Host "$($_.ModifiedEmail)" -ForegroundColor Yellow -NoNewline;
Write-Host " is the user's email prefix, " -NoNewline
#Print PC name to be moved
Write-Host "SD-LT-$($_.PCName)" -ForegroundColor Yellow -NoNewline;
Write-Host " is the PC they use, and " -NoNewline
#Print The OU the computer is moving to
Write-Host "$($_.OU)" -ForegroundColor Yellow -NoNewline;
Write-Host "is the OU the computer needs to go in!"
$pcname = "SD-LT-$($_.PCName)"
Try {
Get-ADComputer SD-LT-$($_.PCName) | Move-ADObject -TargetPath $($_.OU)
}
Catch {
Write-Host $_ -ForegroundColor Magenta
$pcname | Export-csv -Path 'PathToAnotherCSV.csv' -Append -Force
}
}
Try creating a PSCustomObject.
[PSCustomObject]#{'pcname'=$pcname} | Export-csv -Path 'PathToAnotherCSV.csv' -Append -Force

Powershell Output saved to text file and write to console

i am new to powershell, i am trying to make a simple test-connection script that will ping a camera and say if its up or down and if its down save to a txt file.
My issue is, the output in the console works properly but when i go to view the text file it has other random camera names.
[string[]]$CamIP = Get-Content -Path 'C:\Users\johni\Documents\Cams\CamsIP.txt'
[string[]]$CamName = Get-Content -Path 'C:\Users\johni\Documents\Cams\CamNames.txt'
function Get-TimeStamp { return "[{0:MM/dd/yy} {0:HH:mm:ss}]" -f (Get-Date) }
while ($True) {
for ($i = 0; $i -lt ($CamIP.Length); $i++) {
if (Test-Connection $CamIP[$i] -ErrorAction SilentlyContinue) { write-host -ForegroundColor Green -BackgroundColor Black $CamName[$i] "Cam is Up" (Get-Date) }
else {write-host -ForegroundColor Red -BackgroundColor Black $CamName[$i] "Cam is Down" (Get-Date)}
if (Test-Connection $CamIP[$i] -ErrorAction SilentlyContinue) {write-output $CamName[$i] "Cam is Down" (Get-Date) >> 'C:\Users\johni\Documents\Cams\Down Times.txt'}}
Start-Sleep -seconds 5
}
Found the issue,
i forgot to add -NOT on the line that writes to the text file

Powershell outputting info into text file but not into output pane

got a script here which I require the results that export into the text file to also show in the output pane at the bottom. Can anyone help please?
The results I've currently got is that it only shows the Make and model of the machine but not the others from Domain all the way to memory left in GB. I want it all to show on the output pane at the bottom and also to save in a text file which saves and opens straight away.
Please note: The file opens with the data in but the main issue is that it doesn't show in the output pane. Here is the script:
Clear-Host
Write-Host "Setting Execution Policy to Remote Signed..." -ForegroundColor Yellow
Set-ExecutionPolicy RemoteSigned -Force
Write-Host "Your execution policy is set to:" -ForegroundColor Cyan
Get-ExecutionPolicy
Start-Sleep -s 3
Clear-Host
Write-Host "Generating computer statistics..." -ForegroundColor Yellow
Write-Host " "
Start-Sleep -s 2
function systemstats {
Write-Host "Manufacturer:" -ForegroundColor Cyan
Write-Host "$($m.Manufacturer)" -ForegroundColor Yellow
Write-Host "Model:" -ForegroundColor Cyan
Write-Host "$($m.Model)" -ForegroundColor Yellow
Write-Host "Domain:" -ForegroundColor Cyan
$env:USERDOMAIN
Write-Host "Computer Name:" -ForegroundColor Cyan
$env:COMPUTERNAME
Write-Host "Operating System & Location:" -ForegroundColor Cyan
(Get-WmiObject Win32_OperatingSystem).name
Write-Host "OS Architecture:" -ForegroundColor Cyan
if ((Get-WmiObject win32_operatingsystem | select osarchitecture).osarchitecture -eq "64-bit")
{
Write "64-bit OS"
}
else
{
Write "32-bit OS"
}
Write-Host "OS Build:" -ForegroundColor Cyan
(Get-CimInstance Win32_OperatingSystem).version
Write-Host "Version:" -ForegroundColor Cyan
(Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name ReleaseID).ReleaseID
Write-Host "Current IP Address:" -ForegroundColor Cyan
Ipconfig | Select-String IPv4
Write-Host "Calculating RAM installed in MB:" -ForegroundColor Cyan
(systeminfo | Select-String 'Total Physical Memory:').ToString().Split(':')[1].Trim()
$m = (Get-WmiObject -Class Win32_ComputerSystem -Property * |
Select-Object -Property Manufacturer, Model)
Write-Host "Disk Space in GB:" -ForegroundColor Cyan
gwmi win32_logicaldisk | Format-Table DeviceId, MediaType, #{n="Size";e={[math]::Round($_.Size/1GB,2)}},#{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,2)}}
}
$result=(systemstats)
$result | Out-File "C:\Users\brendan.hargate\Desktop\test.txt"
Invoke-Item "C:\Users\brendan.hargate\Desktop\test.txt"
Use Tee-Object instead of Out-File:
$result | Tee-Object -FilePath "C:\Users\brendan.hargate\Desktop\test.txt"
Tee-Object (inspired by tee), will duplicate the input stream - one copy is passed on down the pipeline (which in your case will end up in the command pane), the other is written to a variable or a file (like in the above example)
Your systemstats function in part uses Write-Host which operates outside of PowerShell's (success) output stream.
Write-Host output cannot be captured (PSv4) / is by default not captured (PSv5+) in variables or output files. As the name suggests, Write-Host writes to the host UI (the console), and is not meant to output data - that's what Write-Output and its alias, Write, as well as implicit output (e.g., $env:USERDOMAIN by itself) are for.
A variable assignment such as $result = ... only captures (success) output-stream output, i.e., the implicit output and the output from the Write (a.k.a. Write-Output) command. By contrast, your Write-Host commands printed straight to the console.
Given that you sent $result to a file - without also printing it to the console - the net effect was that only the Write-Host output appeared in the console.
The solution therefore has two components:
Modify your function to only use implicit output (Write-Output output) in order to produce data output.
Then use Tee-Object to print to both the console (via the success output stream) and a file, as suggested in Mathias R. Jessen's helpful answer.
As an aside, in PSv5+, you could get away with the following (although it is ill-advised), based on the ability to capture Write-Host output - now a virtual alias of Write-Information - via the newly introduced output stream number 6:
systemstats 6>&1 | # PSv5+: redirect the information stream to the (success) output stream.
Tee-Object -FilePath "$([Environment]::GetFolderPath('Desktop'))\text.txt"

Export-Csv multiple forloop results

I have multiple forloops running with different variables pulling from .txt files. I want to export this all into a single csv file while having it look just like it does in powershell. Attached is what I get for powershell output and I would like to see the first write-host as a header in excel, followed by server name in column 1 and UP or DOWN in column 2 beneath it.
Powershell
Write-Host "Starting SVR2000MS" -ForegroundColor Yellow
$servers = Get-Content C:\Users\username\Desktop\subfolder\SVR2000.txt
foreach($server in $servers){
if (Test-Connection -ComputerName $server -Count 1 -ErrorAction SilentlyContinue) {
Write-Host "$server, UP" -ForegroundColor Green
}
else{
Write-Host "$server, DOWN" -ForegroundColor Red
}
}
Write-Host "Starting SVR2003DC" -ForegroundColor Yellow
$servers = Get-Content C:\Users\username\Desktop\subfolder\SVR2003.txt
foreach($server in $servers){
if (Test-Connection -ComputerName $server -Count 1 -ErrorAction SilentlyContinue) {
Write-Host "$server, UP" -ForegroundColor Green
}
else{
Write-Host "$server, DOWN" -ForegroundColor Red
}
}
Simple way:
You just print it and put it in a file
Instead of Write-Host ..., do:
"$server,UP" | Out-File test.csv -append
You can have more elaborate options by using objects, but it may be overkill for your needs.
If you want a clean file, you need to delete it at the beginning, because of -append.
BTW, no space after comma in a CSV :)
Edit:
Write-Host writes specifically ... to the host, i.e. the console, so you cannot redirect it elsewhere.

Powershell script to Check and keep program running

Making a short script to keep a program that crashes every now and then running,
Here is what I am trying and been editing
$date = Get-Date -Format G
Function Loop {
{ if(Get-Process -Name notepad -ErrorAction SilentlyContinue) -eq $null
write-host -ForegroundColor red "Server Is Not Running"
.\eldorado.exe -launcher -dedicated -headless -window -height 300 -width 300
echo "Guardian Started Headless Eldorito Server $($date)" | Add-Content .\dedicatedServer.log }
else {write-host -ForegroundColor green "Server Is Running"
sleep 10
Loop
}
Loop
}
What am I doing wrong? / New to scripting / programming
Writing a mash of code, or not copy and pasting properly?
$date = Get-Date -Format G # OK
Function Loop { # OK
# no, your function now starts with a scriptblock
# no, your if () {} pattern is broken.
{if(Get-Process -Name notepad -ErrorAction SilentlyContinue) -eq $null
# ok, but formatting makes it hard to read
write-host -ForegroundColor red "Server Is Not Running"
.\eldorado.exe -launcher -dedicated -headless -window -height 300 -width 300
echo "Guardian Started Headless Eldorito Server $($date)" | Add-Content .\dedicatedServer.log }
#ok
else {write-host -ForegroundColor green "Server Is Running"
sleep 10
# not ok, your loop is now a recursive function call which will consumer more resources forever until it crashes
Loop
}
# what's this doing?
Loop
}
It doesn't seem like you need a function at all, just a loop..
->
$date = Get-Date -Format G
while ($true)
{
if ((Get-Process -Name notepad -ErrorAction SilentlyContinue) -eq $null)
{
Write-Host -ForegroundColor Red "Server Is Not Running"
.\eldorado.exe -launcher -dedicated -headless -window -height 300 -width 300
"Guardian Started Headless Eldorito Server $($date)" | Add-Content .\dedicatedServer.log
}
else
{
write-host -ForegroundColor Green "Server Is Running"
}
Start-Sleep -Seconds 10
}