### Intuitive to Use.Easy to manage.

200.000 administrators have chosen PRTG to monitor their network. Find out how you can reduce cost, increase QoS and ease planning, as well.

### What is this?

This knowledgebase contains questions and answers about PRTG Network Monitor and network monitoring in general. You are invited to get involved by asking and answering questions!

View all Tags

# Can I use placeholders in file names to monitor log files?

#### 0

I want to monitor log files with PRTG. The names of these files contain the date of their creation like, for example, the PRTG webserver logfiles: prtg20160114.log

Because the native file sensor in PRTG does not allow placeholders for the file name, this is not the best option for me to monitor such log files. Is there a way to monitor time stamps and recent changes in the content of files using placeholders in the name for the target file?

Created on Jan 21, 2016 1:19:39 PM by

# Monitoring Files Using Placeholders

The File sensor that comes out of the box with PRTG can monitor a specific file on a disk if you provide the exact path and file name in the sensor settings. This sensor type does not support placeholders to provide the name of the target file. Because log files often have the date of creation in their name, the File sensor might not be perfectly suitable in your scenario.

To monitor log files with date in the name, for example, you can use a custom sensor with a PowerShell script that allows placeholders for the files that you want to monitor. We provide such a sample script below. You can just use the script and adjust the parameters to your scenario. The script also gives you an idea about how to use placeholders for monitoring files in other scenarios.

For this purpose you need an EXE/Script Advanced sensor. This sensor can execute the sample script and shows the following data:

• Number of files that match the pattern of the given file name with placeholders
• Age of oldest and newest file matching the name pattern
• Size of the newest file matching the name pattern
• Total size of files matching the name pattern

See below for the sample script and how to use it.

## How to Use the PowerShell Script

1. Open a text editor.
2. Copy the source code from below and paste it into the editor.
3. Adjust the default values for $path and$include to your scenario. The script as provided below looks for .txt-files in the \temp folder of the target machine. You can also control the script execution with the Parameters setting of the sensor.
4. Save the file with the extension .ps1, for example, “logfileStats.ps1.”
5. Copy this file into your PRTG installation folder, subfolder \Custom Sensors\EXEXML, on the system with the probe from which you want to monitor your files.
6. In PRTG add an EXE/Script Advanced sensor to the target device.
1. Choose logfileStats.ps1 from the list of scripts.
2. Provide the Parameters that you want to use to execute the script. For the sample script, these are the path to the target files and the file name pattern include. For example, to monitor log files of an Apache webserver that have the date right before the file extension, you can provide the following parameter which overrides the defaults: -path \\<unc-path to share>\apache-log\*\ -include Webserver.log-*
4. Click Continue to add the sensor. The sensor will show the retrieved data in the channels Files matching pattern, Oldest File, Newest File, Newest File Size, and Size (see the bullet points above for detailed descriptions).

Note: We do not provide official support for custom sensors. Of course, you are free to adjust the script according to your needs!

## Script

Param(
[string]$path="C:\temp", [string]$include= "*.txt"
)

$result = ""$size = 0
# Get the list of all files
$files = Get-ChildItem -Path$path -include $include -Recurse | Sort-Object LastWriteTime$count = $files.count if ($count -gt 0)
{
$newestfilesize =$files[-1].length
$oldestfile = ("{0:N2}" -f (New-Timespan -end (Get-Date) -start ($files)[0].LastWriteTime).TotalDays).Replace(',','.')
$newestfile = ("{0:N2}" -f (New-Timespan -end (Get-Date) -start ($files)[-1].LastWriteTime).TotalDays).Replace(',','.')
foreach ($file in$files) {
$size +=$file.length
}

$result += @" <result> <value>$count</value>
<unit>count</unit>
<channel>Number of $($include) Files</channel>
</result>
<result>
<value>$oldestfile</value> <unit>custom</unit> <CustomUnit>Days</CustomUnit> <float>1</float> <channel>Oldest File Age</channel> </result> <result> <value>$newestfile</value>
<unit>custom</unit>
<CustomUnit>Days</CustomUnit>
<float>1</float>
</result>
<result>
<value>$newestfilesize</value> <unit>BytesFile</unit> <volumeSize>Byte</volumeSize> <float>0</float> <channel>Newest File Size</channel> </result> <result> <value>$size</value>
<unit>BytesFile</unit>
<volumeSize>Byte</volumeSize>
<channel>Total File Size</channel>
</result>
<text>
OK
</text>
"@
} else {
$result += @" <error>1</error> <text> No file found matching the filter-parameter "$include" at path "$path" </text> "@ } write-host @" <?xml version=1.0 encoding=UTF-8 ?> <prtg>$result
</prtg>
"@

Created on Jan 21, 2016 1:25:12 PM by

Last change on Sep 18, 2018 11:17:54 AM by

#### 0

Hello,

I am currently using the script above, but unfortunately i am getting a 0 Byte value returned for the newest file size. Hopefully you can tell me what i am missing, i do not see the error.

All other values are returned OK, number of files, total file size, ages, even for the newest file the age is returned.

Kind regards,

Kevin

Screenshot:

Parameters PRTG: -path \\dehze01-wsv622\d$\_Qlikview\Production\Data\QVD\IVY\*.QVD -include *.QVD PS1 script: Param( [string]$path="d$\_Qlikview\Production\Data\QVD\IVY\*.QVD", [string]$include= "*.QVD"
)

$result = ""$size = 0
# Get the list of all files
$files = Get-ChildItem -Path$path -include $include -Recurse$count = $files.count if ($count -gt 0)
{
$oldestfile = ("{0:N2}" -f (New-Timespan -end (Get-Date) -start ($files)[0].LastWriteTime).TotalDays).Replace(',','.')
$newestfile = ("{0:N2}" -f (New-Timespan -end (Get-Date) -start ($files)[-1].LastWriteTime).TotalDays).Replace(',','.')
foreach ($file in$files) {
$size +=$file.length
}

$result += @" <result> <value>$count</value>
<unit>count</unit>
<channel>Number of QVD Files</channel>
</result>
<result>
<value>$oldestfile</value> <unit>custom</unit> <CustomUnit>Days</CustomUnit> <float>1</float> <channel>Oldest File Age</channel> </result> <result> <value>$newestfile</value>
<unit>custom</unit>
<CustomUnit>Days</CustomUnit>
<float>1</float>
</result>
<result>
<value>$newestfilesize</value> <unit>BytesFile</unit> <volumeSize>Byte</volumeSize> <float>0</float> <channel>Newest File Size</channel> </result> <result> <value>$size</value>
<unit>BytesFile</unit>
<volumeSize>Byte</volumeSize>
<channel>Total File Size</channel>
</result>
<text>
OK
</text>
"@
} else {
$result += @" <error>1</error> <text> No file found matching the filter-parameter "$include" at path "$path" </text> "@ } write-host @" <?xml version=1.0 encoding=UTF-8 ?> <prtg>$result
</prtg>
"@

Created on Jul 12, 2016 10:08:29 AM by

Last change on Jul 14, 2016 8:04:43 AM by

#### 0

When you execute it manually, what output do you get there?

Created on Jul 13, 2016 12:38:12 PM by

#### 0

Hello,

I am pretty sure there's something in the script which causes this. My knowledge doesn't allow me to fix it, i just copied the above and adjusted the custom options within the script.

Hopefully the creator of the script can give some more detailed information ? perhaps this script doesn't work at all. Still hoping the solution is out there, would hate to go around PRTG making scripts that generate txt output to monitor with PRTG, i liked this script because it just runs from PRTG.

Kind regards,

Kevin

Created on Aug 18, 2016 7:42:28 AM by

#### 0

I'll check out the script and let you know what I find out...

Created on Aug 18, 2016 8:41:50 AM by

#### 0

Turns out that the script had a few bugs:

• $newestfilesize was never defined • newest and oldest file were not correctly sorted (order was alphabetical instead of by LastWriteTime) Updated version can be found in the original answer :) Created on Aug 19, 2016 9:41:23 AM by Last change on Aug 19, 2016 9:41:47 AM by Votes: #### 0 Your Vote: Thank you very, very much ! This is exactly what we where looking for. Thanks again ! Created on Aug 22, 2016 1:24:19 PM by Votes: #### 0 Your Vote: I have problems with the script or sensor. I am getting this : XML: Structural error in xml file, 1 open items. -- JSON: The returned json does not match the expected structure (Invalid JSON.). (code: PE231) I have a DFS file location, which is actually a samba share. I have tried this script first on the machine but thats a unix machine and guessing a ps1 wont work on that. so I picked another server which has acces to that file share. The parameters : ourdomainname.local\dfs\TriathlonFiles\locus\prod\tohost script Param( [string]$path="\\oosterberg.local\dfs\TriathlonFiles\locus\prod\tohost",
[string]$include= "*.dat" )$result = ""
$size = 0 # Get the list of all files$files =  Get-ChildItem -Path $path -include$include -Recurse | Sort-Object LastWriteTime
$count =$files.count
$newestfilesize =$files[-1].length
if ($count -gt 0) {$oldestfile = ("{0:N2}" -f (New-Timespan -end (Get-Date) -start ($files)[0].LastWriteTime).TotalDays).Replace(',','.')$newestfile = ("{0:N2}" -f (New-Timespan -end (Get-Date) -start ($files)[-1].LastWriteTime).TotalDays).Replace(',','.') foreach ($file in $files) {$size += $file.length }$result += @"
<result>
<value>$count</value> <unit>count</unit> <channel>Number of$($include) Files</channel> </result> <result> <value>$oldestfile</value>
<unit>custom</unit>
<CustomUnit>Days</CustomUnit>
<float>1</float>
<channel>Oldest File Age</channel>
</result>
<result>
<value>$newestfile</value> <unit>custom</unit> <CustomUnit>Days</CustomUnit> <float>1</float> <channel>Newest File Age</channel> </result> <result> <value>$newestfilesize</value>
<unit>BytesFile</unit>
<volumeSize>Byte</volumeSize>
<float>0</float>
</result>
<result>
<value>$size</value> <unit>BytesFile</unit> <volumeSize>Byte</volumeSize> <channel>Total File Size</channel> </result> <text> OK </text> "@ } else {$result += @"
<error>1</error>
<text>
No file found matching the filter-parameter "$include" at path "$path"
</text>
"@

}
write-host @"
<?xml version=1.0 encoding=UTF-8 ?>
<prtg>
$result </prtg> "@ Created on Aug 26, 2016 6:18:46 AM by rnijland (0) 1 Votes: #### 0 Your Vote: Did you execute Set-ExecutionPolicy RemoteSigned in a administrative 32bit PowerShell already? Does the script work in a normal powershell? Created on Aug 26, 2016 7:09:40 AM by Last change on Aug 26, 2016 7:10:14 AM by Votes: #### 0 Your Vote: The Get-ExecutionPolicy gives unrestricted back. No it wont work in a normal powershell, it gives this: PS C:\> Get-executionpolicy Unrestricted PS C:\> .\dat-files Unable to index into an object of type System.IO.FileInfo. At C:\DAT-Files.ps1:11 char:26 +$newestfilesize = $files[ <<<< -1].length + CategoryInfo : InvalidOperation: (-1:Int32) [], RuntimeException + FullyQualifiedErrorId : CannotIndex <?xml version=1.0 encoding=UTF-8 ?> <prtg> <error>1</error> <text> No file found matching the filter-parameter "*.dat" at path "\\oosterberg.local\dfs\TriathlonFiles\locus\prod\to host" </text> </prtg> PS C:\> I tried the example script with a C:\temp path and txt file in it, and then the sensor work. I think its something with the pad, though the path I am using is correct Created on Aug 26, 2016 7:34:13 AM by rnijland (0) 1 Votes: #### 0 Your Vote: It's quite possible that PRTG can't access the path properly which would explain the fileinfo exception - it simply can't list any files on there from what it seems. Created on Aug 26, 2016 7:45:04 AM by Votes: #### 0 Your Vote: Yes, I'm trying to get a point with it. Its a share which I can acces from the probe. Its also a share on a unix machine. The root of machine has other credentials to acces but able to acces the shares with windows credentials as samba does the trick. Powershell can user unc paths. I dont see the problem actually, I created the sensor on the probe device. I tried a windows share (windows machine) with a doc file, locally on the probe with powershel the scripts works, when I create a sensor on the probe and it wont work. Created on Aug 26, 2016 7:59:41 AM by rnijland (0) 1 Votes: #### 0 Your Vote: Can you execute Get-ChildItem -Path "\\oosterberg.local\dfs\TriathlonFiles\locus\prod\tohost" ...in a powershell just fine? On the actual probe? Do you run the script on an actual remote probe? Did you set the executionpolicy on the remote probe itself as well? Created on Aug 26, 2016 8:24:54 AM by Votes: #### 0 Your Vote: Hi, after some time testing this i stumbled across the following: • script runs fine on prtg-server • script runs fine on my Window 7 desktop • script runs fine the the server/share to be monitored I want to check, if filenames with text *a9r* are existent in a directory. Existence is bad, absence is good. Sample output, five files found: <?xml version=1.0 encoding=UTF-8 ?> <prtg> <result> <value>5</value> <unit>count</unit> <channel>Number of *a9r* Files**</channel> </result> <result> <value>7,01</value> <unit>custom</unit> <CustomUnit>Days</CustomUnit> <float>1</float> <channel>Oldest File Age</channel> </result> <result> <value>0,00</value> <unit>custom</unit> <CustomUnit>Days</CustomUnit> <float>1</float> <channel>Newest File Age</channel> </result> <result> <value>1673</value> <unit>BytesFile</unit> <volumeSize>Byte</volumeSize> <float>0</float> <channel>Newest File Size</channel> </result> <result> <value>1673</value> <unit>BytesFile</unit> <volumeSize>Byte</volumeSize> <channel>Total File Size</channel> </result> <text> OK Putting it to work in PRTG in Custom Sensors\EXEXML results in No file found matching the filter-parameter "*a9r*" at path SERVER\C$\temp\*. But there are five files present. What else can i try?

Created on Dec 14, 2017 1:34:20 PM by mbn (0)

#### 0

What path are you actually using? If you want to access the administrative C:\ share,
you'll need C$\temp\ instead of \ \<hostname>\C$\temp

Kind regards,

Created on Dec 18, 2017 8:30:42 AM by

#### 0

Update: The monitor is working now, it simply failed because of this setting:

Sicherheitskontext
wrong: Sicherheitskontext des Probe-Dienstes verwenden
right: Die Zugangsdaten für Windows des übergeordneten Geräts verwenden

Path in script (this works, C$\temp\ does not work). The script is executed on PRTG-Server so it seems logic to me to add the SERVER name. Param( [string]$path='\ \SERVER\C$\temp\*', [string]$include= '*a9r*' )

The only thing i am not able to do is to teach him, that absence of a9r is good, presence of a9r is bad. It still needs one a9r in C:\temp file to show green sensor value. Zero a9r-file results in sensor getting grey and red. Any hint on this?

Created on Dec 18, 2017 12:47:28 PM by mbn (0)

#### 0

Is the script actually returning 0 or an empty string as result when no a9r files are present?

Kind regards,

Created on Dec 18, 2017 8:08:09 PM by

#### 0

Zero a9r files:

Yellow (W) Sensor A9R
No file found matching the filter-parameter "*a9r*" at path "\ \SERVER\C$\temp\*" .... i guess this is the result of the else-clause in the script from Gerald Schoch <error>1</error> <text> No file found matching the filter-parameter "$include" at path "$path" </text> "No data" in the channel fields of sensor. After 600 seconds: Red A9R: No file found matching the filter-parameter "*a9r*" at path " ctps01\C$\temp\*"

But running the powershell-script with zero a9r in directory results in

Cannot index into a null array. At D:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXEXML\A9R-check.ps1:11 char:1 + $newestfilesize =$files[-1].length + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : NullArray

Created on Dec 19, 2017 12:37:13 PM by mbn (0)

#### 0

Ah, well you need to capture the error correctly (i.e. output 0 files). Try/Catch is your friend here :)

Kind regards,

Created on Dec 19, 2017 1:06:08 PM by

#### 1

For me, there were two bugs in this script:

## 1: Fails, if only ONE file found

With only ONE file found, this command does not return an array but a single item!

So this IF statement will fail because single item doesn't have a count property:

$count =$files.count
if ($count -gt 0) Therefore, this line$files = Get-ChildItem -Path $path -include$include -Recurse | Sort-Object LastWriteTime

has to be corrected with a surrounding @( ) to always return an array: $files = @(Get-ChildItem -Path$path -include $include -Recurse | Sort-Object LastWriteTime) ## 2: Move$newestfilesize infto IF

$count =$files.count
$newestfilesize =$files[-1].length
if ($count -gt 0) { should be corrected to$count = $files.count if ($count -gt 0)
{
$newestfilesize =$files[-1].length

to prevent errors on an empty array

Created on Sep 18, 2018 10:25:33 AM by ITSE (10)

#### 0

Hi ITSE,

Thanks, I've updated the script accordingly. Much appreciated!

Kind regards,

Created on Sep 18, 2018 11:18:23 AM by

#### 0

Hi guys,

I use the Windows credentials of the parent device. The user has local admin rights on the system where I want to check a folder for avhdx-files. I used these parameters: -path
*Target-Hostname*\C$\ClusterStorage -include *.avhdx. The skript runs on the PRTG-host and on the target host sucessfully. The PRTG-host is a non-domain machine. The target host is a domain-member. I even tried a user with domain-admin rights, but still access denied. Other sensors, which also need credentials, work fine on the target host. Here is the logfile I get, when I tick "Write EXE result to disk": Data['linuxloginpassword'].asString := ''; Data['notonpod'].asString := '0'; Data['fastcount'].asString := '0'; Data['lastmsg'].asString := '#O95'; Data['resultfile'].asString := 'Result of Sensor 4200.txt'; Data['windowsloginusername'].asString := '*user defined in parent device*'; Data['hostv6'].asString := ''; Data['exefile'].asString := 'file-stats.ps1'; Data['lastuptime'].asString := '0'; Data['writeresult'].asString := '1'; Data['blockedsens'].asString := ''; Data['reqmsginterval'].asString := '60'; Data['windowslogindomain'].asString := '*mydomain*'; Data['tlsexplicit_imap'].asString := ''; Data['channelnames'].asString := ''; Data['tlsexplicit_default'].asString := ''; Data['canlinux'].asString := '0'; Data['isexesensor'].asString := '1'; Data['windowsloginpassword'].asString := '***'; Data['environment'].asString := ''; Data['mutexname'].asString := ''; Data['channelinfos'].asString := '{}'; Data['uptimecount'].asString := '0'; Data['interfacenumber'].asString := ''; Data['reboot'].asString := '43507.3921698611'; Data['usednstime'].asString := '0'; Data['linuxlogindomain'].asString := ''; Data['exeparamshash'].asString := 'da39a3ee5e6b4b0d3255bfef95601890afd80709'; Data['tlsexplicit_port'].asString := ''; Data['monitorchange'].asString := ''; Data['inerror'].asString := '1'; Data['inum'].asString := ''; Data['sensorid'].asString := '4200'; Data['ipversion'].asString := '0'; Data['tlsexplicit_smtp'].asString := ''; Data['host'].asString := '*targetip*'; Data['exeparamscache'].asString := ''; Data['usewindowsauthentication'].asString := '1'; Data['simulate'].asString := '0'; Data['tlsexplicit_ftp'].asString := ''; Data['timeout'].asString := '60'; Data['exeparams'].asString := ''; Data['momopersistent'].asString := ''; Data['tlsexplicit_pop3'].asString := ''; Any ideas, what the problem could be? I'm running PRTG 18.4. Thanks, Phil Created on Feb 12, 2019 11:25:25 AM by psc (0) Last change on Feb 12, 2019 11:31:54 AM by Votes: #### 0 Your Vote: Please try the following notation instead: -path '\\%host\C$\ClusterStorage' -include '*.avhdx'

If that doesn't work, please try to execute PowerShell with -noprofile, executing the script within that session:

powershell.exe -noprofile

Kind regards,

Created on Feb 12, 2019 1:12:24 PM by

#### 0

Hi Stephan,

thanks for your fast respond. I tried different Notations, but no effect. I also defined the two parameters directly in the script and tried to run it in PRTG - again access denied.

I run the script on the PRTG-host and on the target-host with the -noprofile parameter - worked both fine.

Created on Feb 12, 2019 3:43:01 PM by psc (0)

#### 0

Is your Probe or Core Service running as a different user by any chance?

Kind regards,

Created on Feb 13, 2019 12:40:07 PM by

#### 0

Both services running as local system.

Created on Feb 15, 2019 6:27:36 AM by psc (0)

#### 0

Then I'm not really sure what the issue could be. Did you try a different folder path and file type?

Kind regards,