|
Replies:
5
-
Pages:
1
-
Last Post:
Dec 9, 2009 7:17 AM
by: jwpj
|
|
|
Posts:
42
Registered:
9/29/09
|
|
|
|
Help with Write-Progress
Posted:
Nov 24, 2009 8:01 AM
|
|
|
First, I'd like to thank Antize for all his help in getting this code put together.
So I have a script here that searches through a filesystem based on a path and name that the user will input. Basically, if an employee is terminated, I want to be able to search the filesystem and find any file that the person is the owner of.
I am in the process of testing it, and I realized that it is going to take a while to search the whole filesystem, so i decided on putting a progress bar to let users know that it is in fact working. Here is my code:
[System.IO.FileInfo] $Path = read-host -prompt "Please enter the path you wish to search." [System.IO.FileInfo] $tmpFile =[System.IO.Path]::GetTempFileName() [string] $User = read-host -prompt "Please enter the unique name of the user you wish to search"
#attempt for a status bar for ($a=100; $a -gt 1; $a--) { Write-Progress -Activity "Working..." ` -SecondsRemaining $a -CurrentOperation "$a% complete" ` -Status "Please wait." Start-Sleep 1 }
#Search for file based on path and username provided. Errors should not display. Get-ChildItem -Path $Path.FullName -Recurse -ErrorAction SilentlyContinue | Where-Object {-not $_.PsIsContainer} | foreach { $currentFile = $_ trap { continue }
$Error.Clear() $Acl = Get-Acl -Path $currentFile.Fullname if ($Error[0] -eq $null) { if ($Acl.Owner -eq $User) { $currentFile.Fullname | Out-File $tmpFile.FullName -append [int] $hits += 1 } } }
if ($hits -gt 0) { notepad.exe $tmpFile.FullName } else { Write-Warning ("No files were found with the owner: " + $User) }
When I try to run it, I'm getting the following error:
You must provide a value expression on the right-hand side of the '-' operator. At E:\scripts\John_Dev\Chris\FSsearch.ps1:22 char:5 + - <<<< Status "Please wait."
I've searched for the error online, but no clear explanation. Anyone have any ideas?
Thanks again all. Message was edited by: jwpj
Message was edited by: jwpj
|
|
|
Posts:
359
Registered:
7/15/08
|
|
|
|
Re: Help with Write-Progress
Posted:
Nov 24, 2009 9:22 AM
in response to: jwpj
|
|
|
It looks like you've missed ` (backtick) symbol at the end of this line:
-SecondsRemaining $a -CurrentOperation
|
|
|
Posts:
122
Registered:
2/21/09
|
|
|
|
Re: Help with Write-Progress
Posted:
Nov 25, 2009 9:26 AM
in response to: jwpj
|
|
|
Yep as Oleg said make sure you get the back tick in there for your line continuation. This will get the code to at least compile however I see a couple issues i'd like to point out.
The way you have write-progress will basically wait 100 seconds before the script actually starts doing anything and will not show progress while it's actually executing which is not what I think you are looking for. It also looks like you want to show a percent complete and estimated time remaining, while cool it is much more difficult to calculate this information. You would have to count all the files in the target folder and keep track of how many files you have processed already to provide an accurate percentage complete metric. Calculating the amount of time left is even more complicated. If you would just like to show the user that script is processing may I suggest the following:
#Search for file based on path and username provided. Errors should not display. Get-ChildItem -Path $Path.FullName -Recurse -ErrorAction SilentlyContinue | Where-Object {-not $_.PsIsContainer} | foreach { $currentFile = $_
Write-Progress -Activity "Searching for file owners..." -CurrentOperation $currentFile.FullName -Status "Current File:" trap { continue }
$Error.Clear() $Acl = Get-Acl -Path $currentFile.Fullname if ($Error[0] -eq $null) { if ($Acl.Owner -eq $User) { $currentFile.Fullname | Out-File $tmpFile.FullName -append [int] $hits += 1 } } }
if ($hits -gt 0) { notepad.exe $tmpFile.FullName } else { Write-Warning ("No files were found with the owner: " + $User) }
The code above won't show a percentage complete or an estimated time remaining, but it will show the user that the script is processing properly.
BTW here is a cool little script I wrote a while ago before the sysinternals suite was available. It would scrub the sysinternals site for tools and download them. It has a write-progress implementation that shows percentage complete -
# Constants [System.Uri]$baseUrl = 'http://live.sysinternals.com' [String]$regex = '/([A-z0-9]*\.(.){0,4}(exe|chm|sys|hlp))'
# Setup output folder [Object]$app = new-object -ComObject Shell.Application [Object]$folder = $app.BrowseForFolder(0, 'Select Folder to Store Sysinternals Tools', 1) [string]$savePath = $folder.Self.Path
if ([System.IO.Directory]::Exists($savePath)) { [System.IO.DirectoryInfo]$outputFolder = Get-Item($savePath) # Use the default proxy configuration $client = New-Object System.Net.WebClient $client.Proxy = [System.Net.WebRequest]::DefaultWebProxy $client.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials # Scrub the page for paths [string]$code = $client.DownloadString($baseUrl) [System.Text.RegularExpressions.MatchCollection]$matches = [regex]::Matches($code, $regex, "IgnoreCase") for ($i=0; $i -lt $matches.Count -1; $i++) { # Setup paths [string]$fileName = $matches[$i].Groups[1].Value [string]$path = Join-Path -Path $outputFolder.FullName -ChildPath $fileName [System.Uri]$url = $baseUrl.AbsoluteUri + $fileName # Show a progress bar with download status [int]$percentComplete = (($i + 1) / $matches.Count) * 100 [string]$activity = 'Downloading ' + $url.AbsoluteUri [string]$status = "Saving " + $path Write-Progress -Activity $activity -Status $status -PercentComplete $percentComplete # Download trap [System.Net.WebException] {write-host ("Error: " + $_ + " Failed to download " + $url + ".") -Foregroundcolor Red; Continue} $client.DownloadFile($url, $path) } explorer.exe $savePath } else { Write-Host The selected path ($savePath) was not valid. }
Message was edited by: antize
|
|
|
Posts:
42
Registered:
9/29/09
|
|
|
|
Re: Help with Write-Progress
Posted:
Nov 30, 2009 6:36 AM
in response to: antize
|
|
|
Thanks guys. Antize, that progress status looks great. The script seems to be doing exactly what I need it to, which is awesome.
I am trying to save the temp file to a specific folder on my desktop using this code:
if ($hits -gt 0) { #notepad.exe $tmpFile.FullName $tmpFile.FullName | out-file 'C:\Documents and Settings\jwpj\Desktop\User_Search_Logs\User_Search-$date.txt' } else { Write-Warning ("No files were found with the owner: " + $User) }
in bold is what i have tried to change in order to accomplish this. Basically I want to put the date on the end of the file, so that every time the script is run, the user will be able to distinguish his run from previous ones. Any reason you can see why this wouldn't work? I'm not seeing the file in that folder.
I set the date variable earlier up in the code $date = get-date
thx
|
|
|
Posts:
122
Registered:
2/21/09
|
|
|
|
Re: Help with Write-Progress
Posted:
Nov 30, 2009 7:12 PM
in response to: jwpj
|
|
|
Sure couple issues there -
1. $date is actually not a built in variable. To see what you have "built-in", start a new shell and use the get-variable cmdlet. To get the date, you'll need to use the Get-Date cmdlet. However, you'll need to format the cmdlet output a little before you can use it in a file name because the default format from get-date will have invalid filename characters. This will format it for you:
"{0:hh-mmtt_MM-dd-yyyy}" -f (get-date)
will look like:
10-06PM_11-30-2009
For more on formatting to make it the way you want it, check this out - http://tfl09.blogspot.com/2007/11/formatting-with-powershell.html (search for "TIME AND DATE")
2. You'll need to use double quotes around a string that contains variables. If you use single quotes, instead of the variable name being replaced with the variable value, you'll get the string $date literally.
3. Make sure to keep the -append parameter for the out-file cmdlet.
Here is some code updated with these tips:
[System.IO.FileInfo] $Path = read-host -prompt "Please enter the path you wish to search."
[string] $User = read-host -prompt "Please enter the unique name of the user you wish to search"
[String] $currentDateTime = "{0:hh-mmtt_MM-dd-yyyy}" -f (get-date) [System.IO.FileInfo] $tmpFile = "C:\Documents and Settings\jwpj\Desktop\User_Search_Logs\User_Search-$currentDateTime.txt"
#Search for file based on path and username provided. Errors should not display. Get-ChildItem -Path $Path.FullName -Recurse -ErrorAction SilentlyContinue | Where-Object {-not $_.PsIsContainer} | foreach { $currentFile = $_
Write-Progress -Activity "Searching for file owners..." -CurrentOperation $currentFile.FullName -Status "Current File:" trap { continue }
$Error.Clear() $Acl = Get-Acl -Path $currentFile.Fullname if ($Error[0] -eq $null) { if ($Acl.Owner -eq $User) { $currentFile.Fullname | Out-File $tmpFile.FullName -append [int] $hits += 1 } } }
if ($hits -gt 0) { notepad.exe $tmpFile.FullName } else { Write-Warning ("No files were found with the owner: " + $User) }
|
|
|
Posts:
42
Registered:
9/29/09
|
|
|
|
Re: Help with Write-Progress
Posted:
Dec 9, 2009 7:17 AM
in response to: jwpj
|
|
|
Thanks to antize for all of his help finalizing this script. It is working fantastic.
|
|
|
|
Legend
|
|
MVP: 2501
+
pts
|
|
Guru: 2001
- 2500
pts
|
|
Expert: 751
- 2000
pts
|
|
Enthusiast: 31
- 750
pts
|
|
Novice: 0
- 30
pts
|
|
Moderators
|
|
Helpful answer
(5 pts)
|
|
Answered
(10 pts)
|
|