Categories
Sponsors
Archive
Blogroll
Badges
Community
|
Posted in Windows Powershell | No Comment | 1,394 views | 04/05/2015 17:23
These are IIS Website Logging properties that you can get using CIM via PowerShell.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| # Get WebSites
$WebSites = Get-CimInstance -Namespace "root\MicrosoftIISv2" -ClassName "IIsWebServerSetting" -OperationTimeoutSec 15 -EA Stop
$WebSite = $WebSites[0];
# WebSite Log Information
[string]$WebSiteLogFormat = $WebSite.LogType
[string]$WebSiteLogDirectory = $WebSite.LogFileDirectory
[string]$WebSiteLogPeriod = $WebSite.LogFilePeriod
[string]$WebSiteLogTruncateSize = $WebSite.LogFileTruncateSize
[string]$WebSiteLogLocalTimeRollover = $WebSite.LogFileLocaltimeRollover
[string]$WebSiteLogState = $WebSite.DontLog
[string]$WebSiteLogExtFileBytesRecv = $WebSite.LogExtFileBytesRecv
[string]$WebSiteLogExtFileBytesSent = $WebSite.LogExtFileBytesSent
[string]$WebSiteLogExtFileClientIp = $WebSite.LogExtFileClientIp
[string]$WebSiteLogExtFileComputerName = $WebSite.LogExtFileComputerName
[string]$WebSiteLogExtFileCookie = $WebSite.LogExtFileCookie
[string]$WebSiteLogExtFileDate = $WebSite.LogExtFileDate
[string]$WebSiteLogExtFileFlags = $WebSite.LogExtFileFlags
[string]$WebSiteLogExtFileHost = $WebSite.LogExtFileHost
[string]$WebSiteLogExtFileHttpStatus = $WebSite.LogExtFileHttpStatus
[string]$WebSiteLogExtFileHttpSubStatus = $WebSite.LogExtFileHttpSubStatus
[string]$WebSiteLogExtFileMethod = $WebSite.LogExtFileMethod
[string]$WebSiteLogExtFileProtocolVersion = $WebSite.LogExtFileProtocolVersion
[string]$WebSiteLogExtFileReferer = $WebSite.LogExtFileReferer
[string]$WebSiteLogExtFileServerIp = $WebSite.LogExtFileServerIp
[string]$WebSiteLogExtFileServerPort = $WebSite.LogExtFileServerPort
[string]$WebSiteLogExtFileSiteName = $WebSite.LogExtFileSiteName
[string]$WebSiteLogExtFileTime = $WebSite.LogExtFileTime
[string]$WebSiteLogExtFileTimeTaken = $WebSite.LogExtFileTimeTaken
[string]$WebSiteLogExtFileUriQuery = $WebSite.LogExtFileUriQuery
[string]$WebSiteLogExtFileUriStem = $WebSite.LogExtFileUriStem
[string]$WebSiteLogExtFileUserAgent = $WebSite.LogExtFileUserAgent
[string]$WebSiteLogExtFileUserName = $WebSite.LogExtFileUserName
[string]$WebSiteLogExtFileWin32Status = $WebSite.LogExtFileWin32Status |
# Get WebSites
$WebSites = Get-CimInstance -Namespace "root\MicrosoftIISv2" -ClassName "IIsWebServerSetting" -OperationTimeoutSec 15 -EA Stop
$WebSite = $WebSites[0];
# WebSite Log Information
[string]$WebSiteLogFormat = $WebSite.LogType
[string]$WebSiteLogDirectory = $WebSite.LogFileDirectory
[string]$WebSiteLogPeriod = $WebSite.LogFilePeriod
[string]$WebSiteLogTruncateSize = $WebSite.LogFileTruncateSize
[string]$WebSiteLogLocalTimeRollover = $WebSite.LogFileLocaltimeRollover
[string]$WebSiteLogState = $WebSite.DontLog
[string]$WebSiteLogExtFileBytesRecv = $WebSite.LogExtFileBytesRecv
[string]$WebSiteLogExtFileBytesSent = $WebSite.LogExtFileBytesSent
[string]$WebSiteLogExtFileClientIp = $WebSite.LogExtFileClientIp
[string]$WebSiteLogExtFileComputerName = $WebSite.LogExtFileComputerName
[string]$WebSiteLogExtFileCookie = $WebSite.LogExtFileCookie
[string]$WebSiteLogExtFileDate = $WebSite.LogExtFileDate
[string]$WebSiteLogExtFileFlags = $WebSite.LogExtFileFlags
[string]$WebSiteLogExtFileHost = $WebSite.LogExtFileHost
[string]$WebSiteLogExtFileHttpStatus = $WebSite.LogExtFileHttpStatus
[string]$WebSiteLogExtFileHttpSubStatus = $WebSite.LogExtFileHttpSubStatus
[string]$WebSiteLogExtFileMethod = $WebSite.LogExtFileMethod
[string]$WebSiteLogExtFileProtocolVersion = $WebSite.LogExtFileProtocolVersion
[string]$WebSiteLogExtFileReferer = $WebSite.LogExtFileReferer
[string]$WebSiteLogExtFileServerIp = $WebSite.LogExtFileServerIp
[string]$WebSiteLogExtFileServerPort = $WebSite.LogExtFileServerPort
[string]$WebSiteLogExtFileSiteName = $WebSite.LogExtFileSiteName
[string]$WebSiteLogExtFileTime = $WebSite.LogExtFileTime
[string]$WebSiteLogExtFileTimeTaken = $WebSite.LogExtFileTimeTaken
[string]$WebSiteLogExtFileUriQuery = $WebSite.LogExtFileUriQuery
[string]$WebSiteLogExtFileUriStem = $WebSite.LogExtFileUriStem
[string]$WebSiteLogExtFileUserAgent = $WebSite.LogExtFileUserAgent
[string]$WebSiteLogExtFileUserName = $WebSite.LogExtFileUserName
[string]$WebSiteLogExtFileWin32Status = $WebSite.LogExtFileWin32Status
You can find more properties in my blog.
Posted in Windows Powershell | No Comment | 3,345 views | 23/04/2015 16:34
** This is alternative custom script to Compress-Archive for wide range compatibility **
I’ve recently installed Windows Server 2016 as Core installation. Due to there is no shell, my old PowerShell script didn’t work:
1
2
3
4
5
6
7
8
| $ShellApplication = New-Object -com Shell.Application
$ZipPackage = $ShellApplication.NameSpace($ZipPath)
foreach($File in $input)
{
$ZipPackage.CopyHere($File.FullName)
Start-Sleep -milliseconds 5
} |
$ShellApplication = New-Object -com Shell.Application
$ZipPackage = $ShellApplication.NameSpace($ZipPath)
foreach($File in $input)
{
$ZipPackage.CopyHere($File.FullName)
Start-Sleep -milliseconds 5
}
As you see, I’ve used Shell Application before. But now, I’m not able to run that on Server 2016 Core.
So I searched on internet about it and found MVP Jeffrey Hick‘s post:
I used that codes and made a zip function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
| function ConvertTo-CompressedFile
{
param([string]$ZipPath)
# Get Files
[string[]]$Files = $input.FullName;
if ($Files -ne $Null)
{
# Load the assembly
[System.Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null
# Check Zip Extension
if ($ZipPath -notlike "*.zip")
{
Write-Output "Please check your zip file path."
break;
}
# Check Zip Path
if(-not (Test-Path($ZipPath)))
{
# Get Zip File Name
$ZipName = $ZipPath.Split("\")[-1]
if ($ZipPath -notlike "*\*")
{
# Get Current Location
$CurrentLocation = (Get-Location).Path
# Get Current Zip File Path
$CurrentZipPath = $CurrentLocation + "\" + $ZipName
# Update Zip Path
$ZipPath = $CurrentZipPath;
}
# Create Zip File
Set-Content $ZipPath ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
# Set File Attributes
(Get-ChildItem $ZipPath).IsReadOnly = $false
}
# Get Zip File
$ZipFile = [System.IO.Compression.ZipFile]::Open($ZipPath,"Update")
foreach($File in $Files)
{
# Get File Name
$FileName = $File.Split("\")[-1]
# Compress File
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($ZipFile,$File,$FileName,"optimal") | Out-Null
# Buffer
Start-Sleep -milliseconds 5
}
# Close Zip File
$ZipFile.Dispose()
# Output Zip Path
$ZipPath
}
} |
function ConvertTo-CompressedFile
{
param([string]$ZipPath)
# Get Files
[string[]]$Files = $input.FullName;
if ($Files -ne $Null)
{
# Load the assembly
[System.Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem") | Out-Null
# Check Zip Extension
if ($ZipPath -notlike "*.zip")
{
Write-Output "Please check your zip file path."
break;
}
# Check Zip Path
if(-not (Test-Path($ZipPath)))
{
# Get Zip File Name
$ZipName = $ZipPath.Split("\")[-1]
if ($ZipPath -notlike "*\*")
{
# Get Current Location
$CurrentLocation = (Get-Location).Path
# Get Current Zip File Path
$CurrentZipPath = $CurrentLocation + "\" + $ZipName
# Update Zip Path
$ZipPath = $CurrentZipPath;
}
# Create Zip File
Set-Content $ZipPath ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
# Set File Attributes
(Get-ChildItem $ZipPath).IsReadOnly = $false
}
# Get Zip File
$ZipFile = [System.IO.Compression.ZipFile]::Open($ZipPath,"Update")
foreach($File in $Files)
{
# Get File Name
$FileName = $File.Split("\")[-1]
# Compress File
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($ZipFile,$File,$FileName,"optimal") | Out-Null
# Buffer
Start-Sleep -milliseconds 5
}
# Close Zip File
$ZipFile.Dispose()
# Output Zip Path
$ZipPath
}
}
So you can easily compress any file on Windows Server 2016.
Usage:
Get-ChildItem MyFile.txt | ConvertTo-CompressedFile C:\MyFile.zip |
Get-ChildItem MyFile.txt | ConvertTo-CompressedFile C:\MyFile.zip
Also it works for current directories:
Get-ChildItem MyFile.txt | ConvertTo-CompressedFile MyFile.zip |
Get-ChildItem MyFile.txt | ConvertTo-CompressedFile MyFile.zip
If zip file is not exist, that will be created by this script.
Note: This script requires .Net 4.5 Core installed on Windows Server 2016.
Posted in Windows Powershell | No Comment | 2,448 views | 21/03/2015 12:28
These are IIS Website Binding Information properties that you can get using CIM via PowerShell.
1
2
3
4
5
6
7
8
| # Get WebSites
$WebSites = Get-CimInstance -Namespace "root\MicrosoftIISv2" -ClassName "IIsWebServerSetting" -OperationTimeoutSec 15 -EA Stop
$WebSite = $WebSites[0];
# WebSite Default Document Information
[string]$WebSiteEnableDefaultDoc = $WebSite.EnableDefaultDoc
[array]$WebSiteDefaultDocs = $WebSite.DefaultDoc.Split(",") |
# Get WebSites
$WebSites = Get-CimInstance -Namespace "root\MicrosoftIISv2" -ClassName "IIsWebServerSetting" -OperationTimeoutSec 15 -EA Stop
$WebSite = $WebSites[0];
# WebSite Default Document Information
[string]$WebSiteEnableDefaultDoc = $WebSite.EnableDefaultDoc
[array]$WebSiteDefaultDocs = $WebSite.DefaultDoc.Split(",")
You can find more properties in my blog.
Posted in Windows Server | No Comment | 2,711 views | 04/03/2015 10:36
If you want to see SQL Server Shrink status, you can use following query:
SELECT
percent_complete,
total_elapsed_time,
start_time,
status,
estimated_completion_time
FROM
sys.dm_exec_requests
WHERE
command = 'DbccFilesCompact' |
SELECT
percent_complete,
total_elapsed_time,
start_time,
status,
estimated_completion_time
FROM
sys.dm_exec_requests
WHERE
command = 'DbccFilesCompact'
You can execute this query via SQL PowerShell cmdlet.
This is also a reminder for me :)
Posted in Windows Powershell | 4 Comments | 2,873 views | 28/02/2015 09:31
Well, if you read first part, now we will continue with text manipulations on PowerShell.
Test File: 424390 lines, 200 MB Microsoft IIS Log
In first part, winner was “System.IO.StreamReader” so I’ll continue with that.
1. Let’s try a Replace on our script:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| $LogFilePath = "C:\large.log"
$FileStream = New-Object -TypeName IO.FileStream -ArgumentList ($LogFilePath), ([System.IO.FileMode]::Open), ([System.IO.FileAccess]::Read), ([System.IO.FileShare]::ReadWrite);
$ReadLogFile = New-Object -TypeName System.IO.StreamReader -ArgumentList ($FileStream, [System.Text.Encoding]::ASCII, $true);
[int]$LineNumber = 0;
# Read Lines
while (!$ReadLogFile.EndOfStream)
{
$LogContent = $ReadLogFile.ReadLine()
$LineNumber++
$LogContent = $LogContent.Replace('\','\\')
}
$ReadLogFile.Close() |
$LogFilePath = "C:\large.log"
$FileStream = New-Object -TypeName IO.FileStream -ArgumentList ($LogFilePath), ([System.IO.FileMode]::Open), ([System.IO.FileAccess]::Read), ([System.IO.FileShare]::ReadWrite);
$ReadLogFile = New-Object -TypeName System.IO.StreamReader -ArgumentList ($FileStream, [System.Text.Encoding]::ASCII, $true);
[int]$LineNumber = 0;
# Read Lines
while (!$ReadLogFile.EndOfStream)
{
$LogContent = $ReadLogFile.ReadLine()
$LineNumber++
$LogContent = $LogContent.Replace('\','\\')
}
$ReadLogFile.Close()
After replace, script execution time: 3.2394121 seconds.
So what happens if I use Regex instead of Replace?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| $LogFilePath = "C:\large.log"
$FileStream = New-Object -TypeName IO.FileStream -ArgumentList ($LogFilePath), ([System.IO.FileMode]::Open), ([System.IO.FileAccess]::Read), ([System.IO.FileShare]::ReadWrite);
$ReadLogFile = New-Object -TypeName System.IO.StreamReader -ArgumentList ($FileStream, [System.Text.Encoding]::ASCII, $true);
[int]$LineNumber = 0;
# Read Lines
while (!$ReadLogFile.EndOfStream)
{
$LogContent = $ReadLogFile.ReadLine()
$LineNumber++
$LogContent = $LogContent -replace "\\", "\\\\"
}
$ReadLogFile.Close() |
$LogFilePath = "C:\large.log"
$FileStream = New-Object -TypeName IO.FileStream -ArgumentList ($LogFilePath), ([System.IO.FileMode]::Open), ([System.IO.FileAccess]::Read), ([System.IO.FileShare]::ReadWrite);
$ReadLogFile = New-Object -TypeName System.IO.StreamReader -ArgumentList ($FileStream, [System.Text.Encoding]::ASCII, $true);
[int]$LineNumber = 0;
# Read Lines
while (!$ReadLogFile.EndOfStream)
{
$LogContent = $ReadLogFile.ReadLine()
$LineNumber++
$LogContent = $LogContent -replace "\\", "\\\\"
}
$ReadLogFile.Close()
Now script execution time: 25.1311866 seconds. So .Net Replace is your best friend :)
Winner: Replace
2. What happens if I use -notlike in my text operation?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| $LogFilePath = "C:\large.log"
$FileStream = New-Object -TypeName IO.FileStream -ArgumentList ($LogFilePath), ([System.IO.FileMode]::Open), ([System.IO.FileAccess]::Read), ([System.IO.FileShare]::ReadWrite);
$ReadLogFile = New-Object -TypeName System.IO.StreamReader -ArgumentList ($FileStream, [System.Text.Encoding]::ASCII, $true);
[int]$LineNumber = 0;
[int]$TestCount = 0;
# Read Lines
while (!$ReadLogFile.EndOfStream)
{
$LogContent = $ReadLogFile.ReadLine()
$LineNumber++
$LogContent = $LogContent.Replace('\','\\')
if ($LogContent -notlike "#*")
{
$TestCount++
}
}
$ReadLogFile.Close() |
$LogFilePath = "C:\large.log"
$FileStream = New-Object -TypeName IO.FileStream -ArgumentList ($LogFilePath), ([System.IO.FileMode]::Open), ([System.IO.FileAccess]::Read), ([System.IO.FileShare]::ReadWrite);
$ReadLogFile = New-Object -TypeName System.IO.StreamReader -ArgumentList ($FileStream, [System.Text.Encoding]::ASCII, $true);
[int]$LineNumber = 0;
[int]$TestCount = 0;
# Read Lines
while (!$ReadLogFile.EndOfStream)
{
$LogContent = $ReadLogFile.ReadLine()
$LineNumber++
$LogContent = $LogContent.Replace('\','\\')
if ($LogContent -notlike "#*")
{
$TestCount++
}
}
$ReadLogFile.Close()
Script takes 50.1493736 seconds.
But do I have another way for this query? Yes, I can use something like this. Let’s try -ne:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| $LogFilePath = "C:\large.log"
$FileStream = New-Object -TypeName IO.FileStream -ArgumentList ($LogFilePath), ([System.IO.FileMode]::Open), ([System.IO.FileAccess]::Read), ([System.IO.FileShare]::ReadWrite);
$ReadLogFile = New-Object -TypeName System.IO.StreamReader -ArgumentList ($FileStream, [System.Text.Encoding]::ASCII, $true);
[int]$LineNumber = 0;
[int]$TestCount = 0;
# Read Lines
while (!$ReadLogFile.EndOfStream)
{
$LogContent = $ReadLogFile.ReadLine()
$LineNumber++
$LogContent = $LogContent.Replace('\','\\')
if ($LogContent.Substring(0,1) -ne "#")
{
$TestCount++
}
}
$ReadLogFile.Close() |
$LogFilePath = "C:\large.log"
$FileStream = New-Object -TypeName IO.FileStream -ArgumentList ($LogFilePath), ([System.IO.FileMode]::Open), ([System.IO.FileAccess]::Read), ([System.IO.FileShare]::ReadWrite);
$ReadLogFile = New-Object -TypeName System.IO.StreamReader -ArgumentList ($FileStream, [System.Text.Encoding]::ASCII, $true);
[int]$LineNumber = 0;
[int]$TestCount = 0;
# Read Lines
while (!$ReadLogFile.EndOfStream)
{
$LogContent = $ReadLogFile.ReadLine()
$LineNumber++
$LogContent = $LogContent.Replace('\','\\')
if ($LogContent.Substring(0,1) -ne "#")
{
$TestCount++
}
}
$ReadLogFile.Close()
Script takes 25.3682308 seconds. OMG! :)
So using -eq/-ne queries 50% faster than -like/-notlike queries. Try to use them if it’s possible.
Winner: -EQ
To be continued.. :)
Posted in Windows Powershell | 4 Comments | 8,514 views | 28/02/2015 04:08
I want to give some performance tips for large text operations on PowerShell.
Test File: 424390 lines, 200 MB Microsoft IIS Log
1. First of all, we have to read file :) Lets try our alternatives:
a. Native command: Get-Content
1
2
3
4
5
6
7
8
9
| $LogFilePath = "C:\large.log"
$Lines = Get-Content $LogFilePath
[int]$LineNumber = 0;
# Read Lines
foreach ($Line in $Lines)
{
$LineNumber++
} |
$LogFilePath = "C:\large.log"
$Lines = Get-Content $LogFilePath
[int]$LineNumber = 0;
# Read Lines
foreach ($Line in $Lines)
{
$LineNumber++
}
If I use this option, script takes: 13.3727013 seconds to read and loop in 424390 lines.
But how about memory usage?
Get-Content stores file into memory, so it’s normal to see high memory usage.
b. Using .Net method: [io.file]::ReadAllLines
1
2
3
4
5
6
7
8
9
| $LogFilePath = "C:\large.log"
$Lines = [io.file]::ReadAllLines($LogFilePath)
[int]$LineNumber = 0;
# Read Lines
foreach ($Line in $Lines)
{
$LineNumber++
} |
$LogFilePath = "C:\large.log"
$Lines = [io.file]::ReadAllLines($LogFilePath)
[int]$LineNumber = 0;
# Read Lines
foreach ($Line in $Lines)
{
$LineNumber++
}
In this option, script takes: 2.0082615 seconds to read and loop in 424390 lines which is extremely fast instead of Get-Content.
Memory usage is less than Get-Content but still too much. Also I can’t capture it but CPU is max 13%.
c. Using .Net method: System.IO.StreamReader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| $LogFilePath = "C:\large.log"
$FileStream = New-Object -TypeName IO.FileStream -ArgumentList ($LogFilePath), ([System.IO.FileMode]::Open), ([System.IO.FileAccess]::Read), ([System.IO.FileShare]::ReadWrite);
$ReadLogFile = New-Object -TypeName System.IO.StreamReader -ArgumentList ($FileStream, [System.Text.Encoding]::ASCII, $true);
[int]$LineNumber = 0;
# Read Lines
while (!$ReadLogFile.EndOfStream)
{
$LogContent = $ReadLogFile.ReadLine()
$LineNumber++
}
$ReadLogFile.Close() |
$LogFilePath = "C:\large.log"
$FileStream = New-Object -TypeName IO.FileStream -ArgumentList ($LogFilePath), ([System.IO.FileMode]::Open), ([System.IO.FileAccess]::Read), ([System.IO.FileShare]::ReadWrite);
$ReadLogFile = New-Object -TypeName System.IO.StreamReader -ArgumentList ($FileStream, [System.Text.Encoding]::ASCII, $true);
[int]$LineNumber = 0;
# Read Lines
while (!$ReadLogFile.EndOfStream)
{
$LogContent = $ReadLogFile.ReadLine()
$LineNumber++
}
$ReadLogFile.Close()
If I use this option, script takes: 1.7062244 seconds to read and loop in 424390 lines. This seems fastest method.
Also memory usage is too low because it reads file line by line. So PowerShell doesn’t hold file in memory.
But in this case, CPU usage is still too high. Probably it’s killing server’s one core at running time. But it’s something that I can’t help :)
Winner: System.IO.StreamReader
In next part, I’ll show you text manipulation tips. See you.
Posted in Hosting & IIS7, Windows Powershell | 1 Comment | 4,992 views | 16/01/2015 14:01
You can get active IIS log file paths with following script.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # Get Web Sites
$WebSites = Get-Website | Select Name, Id, LogFile
foreach ($WebSite in $WebSites)
{
# Clear Variables
$LogFiles = $Null;
$LogFilePath = $Null;
# Get Web Site Information
$SiteName = $WebSite.Name
$SiteID = $WebSite.Id
# Get Web Site Log Path
$LogDirectory = $WebSite.LogFile.Directory -Replace '%SystemDrive%', $env:SystemDrive
$LogPath = $LogDirectory + "\W3SVC" + $SiteID
$LogFiles = Get-ChildItem $LogPath -Filter *.log -EA SilentlyContinue | Sort-Object LastWriteTime -Descending
if ($LogFiles) { $LogFilePath = $LogFiles[0].FullName; $LogFilePath; }
} |
# Get Web Sites
$WebSites = Get-Website | Select Name, Id, LogFile
foreach ($WebSite in $WebSites)
{
# Clear Variables
$LogFiles = $Null;
$LogFilePath = $Null;
# Get Web Site Information
$SiteName = $WebSite.Name
$SiteID = $WebSite.Id
# Get Web Site Log Path
$LogDirectory = $WebSite.LogFile.Directory -Replace '%SystemDrive%', $env:SystemDrive
$LogPath = $LogDirectory + "\W3SVC" + $SiteID
$LogFiles = Get-ChildItem $LogPath -Filter *.log -EA SilentlyContinue | Sort-Object LastWriteTime -Descending
if ($LogFiles) { $LogFilePath = $LogFiles[0].FullName; $LogFilePath; }
}
That will give you path as an output.
|