How i get a Logfile from my Powershellscript - powershell

I would like to record all my inputs and outputs of my Powershell script into a logfile. I've tried a function, but I have to write the function in each line. I have test it with a Start-transcript, I dont know, but I think its only for Errors, it doesn't work really good.
It is possible, if I start my script to get a Log all lines?
for Example:
$u=rene
New-AdUser -Name $u ...
Write-Hoste "New User ist Create $u"
and in my log file should stand:
17.01.2018 13:00 $u=rene
17.01.2018 13:00 New-AdUser -Name $u ...
17.01.2018 13:00 Write-Hoste "New User ist Create $u"
... and everything else (for Example Errors)

If you want to log the entire script, then you could do something like this
#(
$u=rene
New-AdUser -Name $u ...
Write-Hoste "New User ist Create $u"
... Rest of your script
) | Out-file -FilePath \\PathToYourLogFile\Logfile.txt"
That is one way of doing it. One more way of doing it would be using the Start-Transcript at the beginning of your script and ending your script with Stop-Transcript cmdlet and redirecting the output to a text fie. See start-transcript and stop-transcript for details.
I found one example that will create a daily log for your script (if you run it multiple times a day it'll just append to what you have). The log will be in the same folder as your script and it'll clean out any logs older than 15 days.
$VerbosePreference = "Continue"
$LogPath = Split-Path $MyInvocation.MyCommand.Path
Get-ChildItem "$LogPath\*.log" | Where LastWriteTime -LT (Get-Date).AddDays(-15) | Remove-Item -Confirm:$false
$LogPathName = Join-Path -Path $LogPath -ChildPath "$($MyInvocation.MyCommand.Name)-$(Get-Date -Format 'MM-dd-yyyy').log"
Start-Transcript $LogPathName -Append
Then at the end of your script, just add
Stop-Transcript
Here is the link for the same.
If you want to log specific things then you could use Out-File cmdlet at specific and desired places. Hope that helps!

Related

PowerShell get directory of a program

I recently wrote a script and want to share it with my colleagues. It’s a simple copy and paste program that creates log-files after each run. The problem is that I used this: start transcript -Path C:\Users…
The program works fine but if anyone else runs the script it won’t be able to create log-files, since the directory is a copy of mine.
Now to my question: Is there anyway that the program can find out the directory where each user saved the script so it can create a sub-folder in that directory and then dump the logs in there?
Thank you in advance
The path to the folder containing the currently executing script can be obtained through the $PSScriptRoot automatic variable:
Start-Transcript -OutputDirectory $PSScriptRoot
Here's how I record PowerShell sessions using the Start-Transcript cmdlet. It creates a log file, where the script is run from.
#Log File Paths
$Path = Get-Location
$Path = $Path.ToString()
$Date = Get-Date -Format "yyyy-MM-dd-hh-mm-ss"
$Post = "\" + (Get-Date -Format "yyyy-MM-dd-hh-mm-ss") + "-test.log"
$PostLog = $Path + $Post
$PostLog = $PostLog.ToString()
#Start Transcript
Start-Transcript -Path $PostLog -NoClobber -IncludeInvocationHeader
#Your Script
Get-Date
#End Transcript
Stop-Transcript -ErrorAction Ignore

Is it possible to "-passthru" to Log file only and not the console when using "Start-Transcript -Path "$LogOutput"

I have a Powershell script where I want the console to output my custom messages only, but I would like to capture what the command is doing in a log only. Is this possible?
Just to make it clearer with an example below. I want to copy all the Sub Directories and Files as they are in their own directory to a new location:
Start-Transcript -Path "$LogOutput" -IncludeInvocationHeader -Append
Get-ChildItem -Path "$Source" | Copy-Item -Destination "$Destination" -Exclude "File*.xml" -Force -Recurse -PassThru
Stop-Transcript
I then use $? to get the success of the result on the console for my custom messages.
The above shows details I find helpful but it outputs the -PassThru on the console which I do not want to display there. If I don't specify it, it outputs nothing in the Transcript log either.
If I try appending to the copy command ...-PassThru | Out-File -FilePath "$LogOutput" -Append (The same Log used for Transcript) it fails as the log file is locked by the Transcript. Is there a way to make this possible, or will I have to append ...-PassThru | Out-File -FilePath "$LogOutput" -Append to all my commands individually?
Many thanks in advance.

Adding each item from for loop to csv file

I am trying to use power shell to determine whether a server has a particular patch installed based on the KB and if not append the name to a csv. my input file has system names so I want to export that system name if it does not find the patch installed.
here is what i have so far. The export to csv part does not seem to work.
forEach-Object{
try{
$status = wmic /node:#sys.csv qfe list full /format:table | findstr /i $kb_number
if(!$status){
$output_file = New-Item C:\temp\$kb_number.csv -ItemType File
export-csv $output_file -append -Force
}
else{
write-output $status
}
}
catch{
$error_message = $_.Exception.Message
#write-output "the error message is" $error_message
write-output "Could not find any system with this patch installed."
}
}
Why your code might be failing
We don't see where you're setting the values of #sys.csv or $kb_number in the code you shared. Either of those could be throwing you off.
But the real issue is Export-Csv. For one, you're making a new CSV with every iteration of the loop. And for two, you have to pass in some item for the cmdlet to export as a CSV. Right now, you're only providing these values.
$output_file = New-Item C:\temp\$kb_number.csv -ItemType File
Export-csv -Path $output_file -append -Force
Export-Csv requires an input object. You're not giving it one now.
What do you want to export? If you just want a list of computers without a patch, do this instead.
if(-not(Test-path C:\temp\$kb_number.csv)){
#if file doesn't exist, make it
$output_file = New-Item C:\temp\$kb_number.txt -ItemType File
}
#adds computer name if it doesn't have the patch
Add-Content -Path $output_file -Value $computer
General Suggestions
Instead of using ForEach-Object, you might find it's easier to debug if you use a ForEach loop like this.
$computers = Get-Content C:\pathTo\Your\ComputerList.txt
ForEach($computer in $computers){
}
One additional source of trouble is that your code is using older dos commands in WMIC and then tries to use PowerShell to store the records. You don't need to do this and can make it easier on yourself if you swap out the calls to wmic for Get-WmiObject or Get-CimInstance, the PowerShell native versions of the commands.
To do that, change this line:
wmic /node:#sys.csv qfe list full /format:table | findstr /i $kb_number
translates into
$kb_number = "KB4576484"
Get-CimInstance Win32_QuickFixEngineering -Filter "HotfixID = '$kb_number'" -ComputerName $computer
Source Description HotFixID InstalledBy InstalledOn
------ ----------- -------- ----------- -----------
Update KB4576484 NT AUTHORITY\SYSTEM 9/14/2020 12:00:00 AM
You can store the output of that in a variable and then call Export-Csv on it and that should work.
When in doubt, remove the filter part and just get it working to export all patches to a csv. Then add complexity by adding back the filtering statements.

System.IO.FileSystemWatcher and mapped network drives

I use following PowerShell script to monitor a mapped drive for newly created files and write these changes to a csv file.
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = 'Z:\'
$action =
{
$path = $event.SourceEventArgs.FullPath
$changetype = $event.SourceEventArgs.ChangeType
Write-output "$path was $changetype at $(get-date)" >> C:\temp\HostFileList.csv
}
Register-ObjectEvent $watcher 'Created' -Action $action
Get-EventSubscriber
while($true){ sleep -seconds 1 }
The computer I'm running this script on is heavily used by multiple users. Each user will log onto the computer with their own profile, click a desktop batch file to map a network drive folder and save their work there. My script is set up in Local Group Policy to be ran at start up. From what I can tell the script doesn't have any issues running in the background and listening to the mapped drive folder. My problem is that the script refuses to write an output file to the designated location. If I manually run the script, it creates the output file just fine. Also, when I manually run the script with the local GP startup script enabled, I get two entries in my file, which makes me believe the script is running fine from the local GP. Could anyone advise why my script creates an output file when I run it manually, but not when it is ran at startup? Any feedback is much appreciated.
As for this...
Write-output
Write-Output (Microsoft.PowerShell.Utility)
Sends the specified objects to the next command in the pipeline. If
the command is the last command in the pipeline, the objects are
displayed in the console.
Use the file cmdlets
Export-Csv
Out-File
... and the -append parameter. So, collect your properties and pipe to one of them.
| Export-Csv -Path 'C:\temp\HostFileList.csv' -Append -NoTypeInformation
Export-Csv (Microsoft.PowerShell.Utility)
Converts objects into a series of comma-separated value (CSV) strings
and saves the strings to a file.
$AppService = (Get-Service -DisplayName *Application* | Select-Object -Property DisplayName, Status)
$AppService | Export-Csv -Path .\Services.Csv -NoTypeInformation
Get-Content -Path .\Services.Csv
$WinService = (Get-Service -DisplayName *Windows* | Select-Object -Property DisplayName, Status)
$WinService | Export-Csv -Path ./Services.csv -NoTypeInformation -Append
Get-Content -Path .\Services.Csv
"DisplayName","Status"
"Application Layer Gateway Service","Stopped"
"Application Identity","Running"
"Windows Audio Endpoint Builder","Running"
"Windows Audio","Running"
"Windows Event Log","Running"
Out-File (Microsoft.PowerShell.Utility) - PowerShell
Sends output to a file.
-Append Adds the output to the end of an existing file.

Using powershell script with different parameters

I have a script that deletes anything older than a set time. I want to replicate this for other delete jobs with different times and different folders
I am new to Powershell, this script was written with a lot of google assistance
$Minutes=[DateTime]::Now.AddMinutes(-5)
$Timestamp = Get-Date -Format "yyyy-MM-ddTHH-mm-ss"
$Log = "C:\test\logs\_" + $Timestamp + ".log"
Start-Transcript -path $Log -append -Force -NoClobber
try {
function Write-Log($string)
{
$outStr = "" + $Timestamp +" "+$string
Write-Output $outStr
}
Write-Log "------------ Start of Log ------------"
#Write-Log ""
# get all file objects to use in erasing
$files=Get-ChildItem -path 'c:\test\*' -Include *.* -Recurse |
Where-Object{ $_.LastWriteTime -lt $Minutes}
# Remove the file and its folder.
$files |
ForEach-Object{
Write-Log " Deleting File --> $_."; Remove-Item $_.Fullname
}
# output statistics
Write-Output "**********************"
Write-Output "Number of old files deleted: $($files.Count)"
Write-Log "------------- End of Log -------------"
}
catch {
Write-Error -Message "Something bad happened!" -ErrorAction Stop
}
Stop-Transcript
Welcome to PowerShell, and good for you on the web search approach. Yet remember, it is vital that being new to this, that you take some time to ramp up on all the basic before you diving into this space, in order to avoid as much undue confusion, frustration, etc., that you will encounter.
You really need to do this also to understand what you need, and to avoid having / causing catastrophic issues to your system and or your enterprise. Of course, never run any code you do not fully understand, and always list out your goals and address them one at a time to make sure you are getting the results you'd expect.
Live on YouTube, Microsoft Virtual Academy, Microsoft Learn, TechNet Virtual Labs, MS Channel9, leveraging all the videos you can consume; then hit the documentation/help files, and all the no cost eBooks all over the web.
As for ...
I want to replicate this for other delete jobs with different times
and different folders
… this is why functions and parameters exist.
Function Start-DeleteJob
{
[CmdletBinding()]
[Alias('sdj')]
Param
(
$JobTime,
$JobFolder
)
# Code begins here
}
So, spend time researching PowerShell functions, advance functions, and parameters.
Get-Help -Name About_*Functions*
Get-Help -Name About_*Parameters*