Skip to content

Commit f18f516

Browse files
regedit32johlju
authored andcommitted
Added LogCustomFields to xWebSite (dsccommunity#342)
- Updated xWebSite to include ability to manage custom logging fields (issue dsccommunity#267).
1 parent 6dc1bc8 commit f18f516

8 files changed

+496
-18
lines changed

.MetaTestOptIn.json

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[
2+
"null"
3+
]

DSCResources/MSFT_xWebsite/MSFT_xWebsite.psm1

+164-7
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ data LocalizedData
4949
VerboseSetTargetUpdateLogTruncateSize = TruncateSize does not match and will be updated on Website "{0}".
5050
VerboseSetTargetUpdateLoglocalTimeRollover = LoglocalTimeRollover does not match and will be updated on Website "{0}".
5151
VerboseSetTargetUpdateLogFormat = LogFormat is not in the desired state and will be updated on Website "{0}"
52+
VerboseSetTargetUpdateLogCustomFields = LogCustomFields is not in the desired state and will be updated on Website "{0}"
5253
VerboseTestTargetFalseEnsure = The Ensure state for website "{0}" does not match the desired state.
5354
VerboseTestTargetFalsePhysicalPath = Physical Path of website "{0}" does not match the desired state.
5455
VerboseTestTargetFalseState = The state of website "{0}" does not match the desired state.
@@ -69,6 +70,7 @@ data LocalizedData
6970
VerboseTestTargetFalseLogTruncateSize = LogTruncateSize does not match desired state on Website "{0}".
7071
VerboseTestTargetFalseLoglocalTimeRollover = LoglocalTimeRollover does not match desired state on Website "{0}".
7172
VerboseTestTargetFalseLogFormat = LogFormat does not match desired state on Website "{0}".
73+
VerboseTestTargetFalseLogCustomFields = LogCustomFields does not match desired state on Website "{0}".
7274
VerboseConvertToWebBindingIgnoreBindingInformation = BindingInformation is ignored for bindings of type "{0}" in case at least one of the following properties is specified: IPAddress, Port, HostName.
7375
VerboseConvertToWebBindingDefaultPort = Port is not specified. The default "{0}" port "{1}" will be used.
7476
VerboseConvertToWebBindingDefaultCertificateStoreName = CertificateStoreName is not specified. The default value "{0}" will be used.
@@ -130,6 +132,8 @@ function Get-TargetResource
130132
$webConfiguration = $websiteAutoStartProviders | `
131133
Where-Object -Property Name -eq -Value $ServiceAutoStartProvider | `
132134
Select-Object Name,Type
135+
136+
$cimLogCustomFields = ConvertTo-CimLogCustomFields -InputObject $website.logFile.customFields.Collection
133137
}
134138
# Multiple websites with the same name exist. This is not supported and is an error
135139
else
@@ -161,6 +165,7 @@ function Get-TargetResource
161165
LogtruncateSize = $website.logfile.truncateSize
162166
LoglocalTimeRollover = $website.logfile.localTimeRollover
163167
LogFormat = $website.logfile.logFormat
168+
LogCustomFields = $cimLogCustomFields
164169
}
165170
}
166171

@@ -244,7 +249,10 @@ function Set-TargetResource
244249

245250
[ValidateSet('IIS','W3C','NCSA')]
246251
[String]
247-
$LogFormat
252+
$LogFormat,
253+
254+
[Microsoft.Management.Infrastructure.CimInstance[]]
255+
$LogCustomFields
248256
)
249257

250258
Assert-Module
@@ -491,7 +499,7 @@ function Set-TargetResource
491499
-Name LogFile.period -Value 'MaxSize'
492500
}
493501

494-
# Update LoglocalTimeRollover if neeed
502+
# Update LoglocalTimeRollover if needed
495503
if ($PSBoundParameters.ContainsKey('LoglocalTimeRollover') -and `
496504
($LoglocalTimeRollover -ne `
497505
([System.Convert]::ToBoolean($website.logfile.LocalTimeRollover))))
@@ -501,7 +509,6 @@ function Set-TargetResource
501509
Set-ItemProperty -Path "IIS:\Sites\$Name" `
502510
-Name LogFile.localTimeRollover -Value $LoglocalTimeRollover
503511
}
504-
505512
}
506513
# Create website if it does not exist
507514
else
@@ -740,7 +747,7 @@ function Set-TargetResource
740747
-Name LogFile.period -Value 'MaxSize'
741748
}
742749

743-
# Update LoglocalTimeRollover if neeed
750+
# Update LoglocalTimeRollover if needed
744751
if ($PSBoundParameters.ContainsKey('LoglocalTimeRollover') -and `
745752
($LoglocalTimeRollover -ne `
746753
([System.Convert]::ToBoolean($website.logfile.LocalTimeRollover))))
@@ -751,6 +758,15 @@ function Set-TargetResource
751758
-Name LogFile.localTimeRollover -Value $LoglocalTimeRollover
752759
}
753760
}
761+
762+
# Update LogCustomFields if needed
763+
if ($PSBoundParameters.ContainsKey('LogCustomFields') -and `
764+
(-not (Test-LogCustomField -Site $Name -LogCustomField $LogCustomFields)))
765+
{
766+
Write-Verbose -Message ($LocalizedData.VerboseSetTargetUpdateLogCustomFields `
767+
-f $Name)
768+
Set-LogCustomField -Site $Name -LogCustomField $LogCustomFields
769+
}
754770
}
755771
# Remove website
756772
else
@@ -850,7 +866,10 @@ function Test-TargetResource
850866

851867
[ValidateSet('IIS','W3C','NCSA')]
852868
[String]
853-
$LogFormat
869+
$LogFormat,
870+
871+
[Microsoft.Management.Infrastructure.CimInstance[]]
872+
$LogCustomFields
854873
)
855874

856875
Assert-Module
@@ -1058,6 +1077,15 @@ function Test-TargetResource
10581077
-f $Name)
10591078
return $false
10601079
}
1080+
1081+
# Check LogCustomFields if needed
1082+
if ($PSBoundParameters.ContainsKey('LogCustomFields') -and `
1083+
(-not (Test-LogCustomField -Site $Name -LogCustomField $LogCustomFields)))
1084+
{
1085+
Write-Verbose -Message ($LocalizedData.VerboseTestTargetUpdateLogCustomFields `
1086+
-f $Name)
1087+
return $false
1088+
}
10611089
}
10621090

10631091
if ($inDesiredState -eq $true)
@@ -1587,6 +1615,44 @@ function ConvertTo-WebBinding
15871615
}
15881616
}
15891617

1618+
<#
1619+
.SYNOPSIS
1620+
Converts IIS custom log field collection to instances of the MSFT_xLogCustomFieldInformation CIM class.
1621+
#>
1622+
function ConvertTo-CimLogCustomFields
1623+
{
1624+
[CmdletBinding()]
1625+
[OutputType([Microsoft.Management.Infrastructure.CimInstance[]])]
1626+
param
1627+
(
1628+
[Parameter(Mandatory = $true)]
1629+
[AllowEmptyCollection()]
1630+
[AllowNull()]
1631+
[Object[]]
1632+
$InputObject
1633+
)
1634+
1635+
$cimClassName = 'MSFT_xLogCustomFieldInformation'
1636+
$cimNamespace = 'root/microsoft/Windows/DesiredStateConfiguration'
1637+
$cimCollection = New-Object -TypeName 'System.Collections.ObjectModel.Collection`1[Microsoft.Management.Infrastructure.CimInstance]'
1638+
1639+
foreach ($customField in $InputObject)
1640+
{
1641+
$cimProperties = @{
1642+
LogFieldName = $customField.LogFieldName
1643+
SourceName = $customField.SourceName
1644+
SourceType = $customField.SourceType
1645+
}
1646+
1647+
$cimCollection += (New-CimInstance -ClassName $cimClassName `
1648+
-Namespace $cimNamespace `
1649+
-Property $cimProperties `
1650+
-ClientOnly)
1651+
}
1652+
1653+
return $cimCollection
1654+
}
1655+
15901656
<#
15911657
.SYNOPSYS
15921658
Formats the input IP address string for use in the bindingInformation attribute.
@@ -1747,6 +1813,48 @@ function Set-AuthenticationInfo
17471813
}
17481814
}
17491815

1816+
<#
1817+
.SYNOPSIS
1818+
Helper function used to set the LogCustomField for a website.
1819+
1820+
.PARAMETER Site
1821+
Specifies the name of the Website.
1822+
1823+
.PARAMETER LogCustomField
1824+
A CimInstance collection of what the LogCustomField should be.
1825+
#>
1826+
function Set-LogCustomField
1827+
{
1828+
[CmdletBinding()]
1829+
param
1830+
(
1831+
[Parameter(Mandatory = $true)]
1832+
[String]
1833+
$Site,
1834+
1835+
[Parameter(Mandatory = $true)]
1836+
[ValidateNotNullOrEmpty()]
1837+
[Microsoft.Management.Infrastructure.CimInstance[]]
1838+
$LogCustomField
1839+
)
1840+
1841+
$setCustomFields = @()
1842+
foreach ($customField in $LogCustomField)
1843+
{
1844+
$setCustomFields += @{
1845+
logFieldName = $customField.LogFieldName
1846+
sourceName = $customField.SourceName
1847+
sourceType = $customField.SourceType
1848+
}
1849+
}
1850+
1851+
# The second Set-WebConfigurationProperty is to handle an edge case where logfile.customFields is not updated correctly. May be caused by a possible bug in the IIS provider
1852+
for ($i = 1; $i -le 2; $i++)
1853+
{
1854+
Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter "system.applicationHost/sites/site[@name='$Site']/logFile/customFields" -Name "." -Value $setCustomFields
1855+
}
1856+
}
1857+
17501858
<#
17511859
.SYNOPSIS
17521860
Helper function used to test the authenticationProperties state for an Application.
@@ -2002,6 +2110,57 @@ function Test-WebsiteBinding
20022110
return $inDesiredState
20032111
}
20042112

2113+
<#
2114+
.SYNOPSIS
2115+
Helper function used to test the LogCustomField state for a website.
2116+
2117+
.PARAMETER Site
2118+
Specifies the name of the Website.
2119+
2120+
.PARAMETER LogCustomField
2121+
A CimInstance collection of what state the LogCustomField should be.
2122+
#>
2123+
function Test-LogCustomField
2124+
{
2125+
[CmdletBinding()]
2126+
[OutputType([Boolean])]
2127+
param
2128+
(
2129+
[Parameter(Mandatory = $true)]
2130+
[String]
2131+
$Site,
2132+
2133+
[Parameter(Mandatory=$true)]
2134+
[ValidateNotNullOrEmpty()]
2135+
[Microsoft.Management.Infrastructure.CimInstance[]]
2136+
$LogCustomField
2137+
)
2138+
2139+
$inDesiredSate = $true
2140+
2141+
foreach ($customField in $LogCustomField)
2142+
{
2143+
$filterString = "/system.applicationHost/sites/site[@name='{0}']/logFile/customFields/add[@logFieldName='{1}']" -f $Site, $customField.LogFieldName
2144+
$presentCustomField = Get-WebConfigurationProperty -Filter $filterString -Name "."
2145+
2146+
if ($presentCustomField)
2147+
{
2148+
$sourceNameMatch = $customField.SourceName -eq $presentCustomField.SourceName
2149+
$sourceTypeMatch = $customField.SourceType -eq $presentCustomField.sourceType
2150+
if (-not ($sourceNameMatch -and $sourceTypeMatch))
2151+
{
2152+
$inDesiredSate = $false
2153+
}
2154+
}
2155+
else
2156+
{
2157+
$inDesiredSate = $false
2158+
}
2159+
}
2160+
2161+
return $inDesiredSate
2162+
}
2163+
20052164
<#
20062165
.SYNOPSIS
20072166
Helper function used to update default pages of website.
@@ -2143,5 +2302,3 @@ function Update-WebsiteBinding
21432302
#endregion
21442303

21452304
Export-ModuleMember -Function *-TargetResource
2146-
2147-

DSCResources/MSFT_xWebsite/MSFT_xWebsite.schema.mof

+9
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ class MSFT_xWebAuthenticationInformation
2121
[Write] Boolean Windows;
2222
};
2323

24+
[ClassVersion("1.0.0")]
25+
class MSFT_xLogCustomFieldInformation
26+
{
27+
[Write] String LogFieldName;
28+
[Write] String SourceName;
29+
[Write, ValueMap{"RequestHeader","ResponseHeader","ServerVariable"},Values{"RequestHeader","ResponseHeader","ServerVariable"}] String SourceType;
30+
};
31+
2432
[ClassVersion("2.0.0"), FriendlyName("xWebsite")]
2533
class MSFT_xWebsite : OMI_BaseResource
2634
{
@@ -43,4 +51,5 @@ class MSFT_xWebsite : OMI_BaseResource
4351
[Write, Description ("How large the file should be before it is truncated")] String LogTruncateSize;
4452
[Write, Description ("Use the localtime for file naming and rollover")] Boolean LoglocalTimeRollover;
4553
[Write, Description ("Format of the Logfiles. Only W3C supports LogFlags"), ValueMap{"IIS","W3C","NCSA"}, Values{"IIS","W3C","NCSA"}] String LogFormat;
54+
[Write, EmbeddedInstance("MSFT_xLogCustomFieldInformation"), Description("Custom logging field information in the form of an array of embedded instances of MSFT_xLogCustomFieldInformation CIM class")] String LogCustomFields[];
4655
};

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ Please check out common DSC Resources [contributing guidelines](https://github.c
185185
* **LogTruncateSize**: How large the file should be before it is truncated. If this is set then LogPeriod will be ignored if passed in and set to MaxSize. The value must be a valid integer between `1048576 (1MB)` and `4294967295 (4GB)`.
186186
* **LoglocalTimeRollover**: Use the localtime for file naming and rollover. The acceptable values for this property are: `$true`, `$false`
187187
* **LogFormat**: Format of the Logfiles. **Note**Only W3C supports LogFlags. The acceptable values for this property are: `IIS`,`W3C`,`NCSA`
188+
* **LogCustomFields**: Custom logging field information the form of an array of embedded instances of the **MSFT_xLogCustomFieldInformation** CIM class that implements the following properties:
189+
* **LogFieldName**: Field name to identify the custom field within the log file. Please note that the field name cannot contain spaces.
190+
* **SourceName**: You can select `RequestHeader`, `ResponseHeader`, or `ServerVariable` (note that enhanced logging cannot log a server variable with a name that contains lower-case characters - to include a server variable in the event log just make sure that its name consists of all upper-case characters).
191+
* **SourceType**: Name of the HTTP header or server variable (depending on the Source Type you selected) that contains a value that you want to log.
188192

189193
### xWebApplication
190194

@@ -257,6 +261,7 @@ Please check out common DSC Resources [contributing guidelines](https://github.c
257261
## Versions
258262

259263
### Unreleased
264+
* Updated **xWebSite** to include ability to manage custom logging fields
260265

261266
### 1.20.0.0
262267

Tests/Integration/MSFT_xWebsite.Integration.Tests.ps1

+16-2
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,14 @@ try
123123
#Test DefaultPage is correct
124124
$defultPages[0] | Should Match $dscConfig.AllNodes.DefaultPage
125125

126-
}
126+
#Test LogCustomFields is correct
127+
$result.logFile.customFields.Collection[0].LogFieldName | Should Be $dscConfig.AllNodes.LogFieldName1
128+
$result.logFile.customFields.Collection[0].SourceName | Should Be $dscConfig.AllNodes.SourceName1
129+
$result.logFile.customFields.Collection[0].SourceType | Should Be $dscConfig.AllNodes.SourceType1
130+
$result.logFile.customFields.Collection[1].LogFieldName | Should Be $dscConfig.AllNodes.LogFieldName2
131+
$result.logFile.customFields.Collection[1].SourceName | Should Be $dscConfig.AllNodes.SourceName2
132+
$result.logFile.customFields.Collection[1].SourceType | Should Be $dscConfig.AllNodes.SourceType2
133+
}
127134

128135
}
129136

@@ -195,7 +202,14 @@ try
195202
#Test DefaultPage is correct
196203
$defultPages[0] | Should Match $dscConfig.AllNodes.DefaultPage
197204

198-
}
205+
#Test LogCustomFields is correct
206+
$result.logFile.customFields.Collection[0].LogFieldName | Should Be $dscConfig.AllNodes.LogFieldName1
207+
$result.logFile.customFields.Collection[0].SourceName | Should Be $dscConfig.AllNodes.SourceName1
208+
$result.logFile.customFields.Collection[0].SourceType | Should Be $dscConfig.AllNodes.SourceType1
209+
$result.logFile.customFields.Collection[1].LogFieldName | Should Be $dscConfig.AllNodes.LogFieldName2
210+
$result.logFile.customFields.Collection[1].SourceName | Should Be $dscConfig.AllNodes.SourceName2
211+
$result.logFile.customFields.Collection[1].SourceType | Should Be $dscConfig.AllNodes.SourceType2
212+
}
199213

200214
}
201215

0 commit comments

Comments
 (0)