Problems when configuring Advance IIS logs with Powershell - asp.net

The objectives of this script:
Create a new folder for each site
Create one log per site per day
A second script to backup/arhive scripts within a certain format
Stop all normal logging
# Ensure cmdlets are available
Import-Module WebAdministration
$Websites = (Get-Website).Name
foreach($site in $websites)
{
Stop-Website $site
}
# Disables http logging module
Set-WebConfigurationProperty -Filter system.webServer/httpLogging -PSPath
machine/webroot/apphost -Name dontlog -Value true
# Disables the default advanced logging config
Set-WebConfigurationProperty -Filter "system.webServer/advancedLogging/server
/logDefinitions/logDefinition[#baseFileName='%COMPUTERNAME%-Server']" -name
enabled -value false
# Enable Advanced Logging
Set-WebConfigurationProperty -Filter system.webServer/advancedLogging/server
-PSPath machine/webroot/apphost -Name enabled -Value true
# Move to location to store iis logs
cd C:\inetpub\Logs\Advancedlogs
# Create Folders if required
Foreach($site in $websites)
{
$FoldersPresent = Test-Path "C:\inetpub\logs\AdvancedLogs\$site"
if($FoldersPresent -eq $true)
{
Write-host "Folder exsists"
}
else
{
New-Item -ItemType directory $site
}
}
# Create hash table
$list = #{'Win32Status'='sc-win32-status';'URI-Stem'='cs-uri-stem';
'URI-Querystring'='cs-uri-query';'Time-UTC'='time';'Time-Local'='time-
local';'Take Taken'='TimeTakenMS';'Substatus'='sc-substatus';'Status'='sc-
status';'Site Name'='s-sitename';'Server-IP'='s-ip';'Server Port'='s-port';
'Server Name'='s-computername';'Protocol Version'='cs-version';'Protocol'='c-
protocol';'Method'='cs-method';'Date-UTC'='date';'Date-Local'='date-local';
'ContentPath'='s-contentpath';'Client-IP'='c-ip';'EndRequest-UTC'='EndRequest-
UTC';'Bytes Sent'='sc-bytes';'Bytes Received'='cs-bytes';'BeginRequest-
UTC'='BeginRequest-UTC';'UserName'='cs-username';'User Agent'='cs(User-
Agent)';'Referer'='cs(Referer)';'Proxy'='s-proxy';'Host'='cs(Host)';
'Cookie'='cs(Cookie)'}
# Set the log file fields
foreach($site in $Websites)
{
$AppName = $site
$appdrive = "C:\inetpub\logs\AdvancedLogs\$site"
$LogRotateFreq = "Daily"
Add-WebConfiguration /system.webServer/advancedLogging/Server
/logDefinitions IIS:\ -Location $AppName -value
#{baseFileName="%COMPUTERNAME%-$AppName";enabled="true";
logRollOption="Schedule";schedule=$LogRotateFreq;publishLogEvent="false"}
$list.GetEnumerator() | foreach {
Add-WebConfiguration "/system.webServer/advancedLogging/Server/logDefinitions/logDefinition[#baseFileName=""%COMPUTERNAME%-$AppName""]/selectedFields" IIS:\ -Location $AppName -value #{defaultValue="";required="false";logHeaderName=$_.Name;id=$_.Value;}
Set-WebConfiguration "/system.applicationHost/Sites/Site[#name=""$AppName""]/advancedLogging" -value #{directory="$appdrive"}
}
}
# Start the websites
foreach($site in $websites)
{
Start-Website $site
}
Links used for guidance:
http://forums.iis.net/t/1185802.aspx?No+log+files+created+by+Advanced+Logging
http://forums.iis.net/t/1193633.aspx?Configure+Advanced+Logging+through+powershellhttp://www.antonyfrancis.net/2014/01/automated-installation-and.html

Related

Azure Powershell - Problem with assigning private IP address to an NIC

Here is my script
$my_vnet = Get-AzVirtualNetwork -Name <vnet_name>
$my_subnet = Get-AzVirtualNetworkSubnetConfig -Name <subnet_name> -VirtualNetwork $my_vnet
Add-AzNetworkInterfaceIpConfig -Name ext-ipconfig6 -NetworkInterface $my_nic -
Subnet $my_subnet -PrivateIpAddress 10.0.0.6
There is no error when running the script. If I use the following command to check, I do see the IP object created.
Get-AzNetworkInterfaceIpConfig -Name ext-ipconfig6 -NetworkInterface $my_nic
...
{
"Name": "ext-ipconfig6",
"PrivateIpAddress": "10.0.0.6",
"PrivateIpAllocationMethod": "Static",
"Subnet": {
"Id": "blabla"
},
"Primary": false
}
However, I don't see it created on the portal.
Comparing with others created in the portal, I see other properties like Etag, Id, ProvisioningState, ...etc. Where did I do wrong...?
Thanks!
You are just creating the Network Interface IP configuration and not setting it to the existing Network interface itself.
I tested the same script which resulted as below :
To fix the above you will have to add | Set-AzNetworkInterface after the Add-AzNetworkInterfaceIpConfig command like below :
$vnet = Get-AzVirtualNetwork -Name "ansuman-vnet" -ResourceGroupName "ansumantest"
$nic= Get-AzNetworkInterface -Name "ansumannic01" -ResourceGroupName "ansumantest"
Add-AzNetworkInterfaceIpConfig -Name "IPConfig2" -NetworkInterface $nic -Subnet $vnet.Subnets[0] -PrivateIpAddress "10.0.0.7" | Set-AzNetworkInterface
Output:

MSB4018 Error Visual Studio 2015 ASP.Net and Error Publish Web App to Azure

I am working with Visual Studio 2015 Community with Azure 2.9 For the first time. I tried creating a brand new ASP.Net Web Application. The default template build and viewed in the Browser with no issues.
I tried publishing the site using Azure. When doing so I get this error
The "InvokePowerShell" task failed unexpectedly.
System.Management.Automation.CommandNotFoundException: The term '[cmdletbinding(SupportsShouldProcess=$true)]
param($publishProperties, $packOutput, $nugetUrl)
# to learn more about this file visit http://go.microsoft.com/fwlink/?LinkId=524327
$publishModuleVersion = '1.0.1'
function Get-VisualStudio2015InstallPath{
[cmdletbinding()]
param()
process{
$keysToCheck = #('hklm:\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0',
'hklm:\SOFTWARE\Microsoft\VisualStudio\14.0',
'hklm:\SOFTWARE\Wow6432Node\Microsoft\VWDExpress\14.0',
'hklm:\SOFTWARE\Microsoft\VWDExpress\14.0'
)
[string]$vsInstallPath=$null
foreach($keyToCheck in $keysToCheck){
if(Test-Path $keyToCheck){
$vsInstallPath = (Get-itemproperty $keyToCheck -Name InstallDir -ErrorAction SilentlyContinue | select -ExpandProperty InstallDir -ErrorAction SilentlyContinue)
}
if($vsInstallPath){
break;
}
}
$vsInstallPath
}
}
$vsInstallPath = Get-VisualStudio2015InstallPath
$publishModulePath = "{0}Extensions\Microsoft\Web Tools\Publish\Scripts\{1}\" -f $vsInstallPath, $publishModuleVersion
if(!(Test-Path $publishModulePath)){
$publishModulePath = "{0}VWDExpressExtensions\Microsoft\Web Tools\Publish\Scripts\{1}\" -f $vsInstallPath, $publishModuleVersion
}
$defaultPublishSettings = New-Object psobject -Property #{
LocalInstallDir = $publishModulePath
}
function Enable-PackageDownloader{
[cmdletbinding()]
param(
$toolsDir = "$env:LOCALAPPDATA\Microsoft\Web Tools\Publish\package-downloader-$publishModuleVersion\",
$pkgDownloaderDownloadUrl = 'http://go.microsoft.com/fwlink/?LinkId=524325') # package-downloader.psm1
process{
if(get-module package-downloader){
remove-module package-downloader | Out-Null
}
if(!(get-module package-downloader)){
if(!(Test-Path $toolsDir)){ New-Item -Path $toolsDir -ItemType Directory -WhatIf:$false }
$expectedPath = (Join-Path ($toolsDir) 'package-downloader.psm1')
if(!(Test-Path $expectedPath)){
'Downloading [{0}] to [{1}]' -f $pkgDownloaderDownloadUrl,$expectedPath | Write-Verbose
(New-Object System.Net.WebClient).DownloadFile($pkgDownloaderDownloadUrl, $expectedPath)
}
if(!$expectedPath){throw ('Unable to download package-downloader.psm1')}
'importing module [{0}]' -f $expectedPath | Write-Output
Import-Module $expectedPath -DisableNameChecking -Force
}
}
}
function Enable-PublishModule{
[cmdletbinding()]
param()
process{
if(get-module publish-module){
remove-module publish-module | Out-Null
}
if(!(get-module publish-module)){
$localpublishmodulepath = Join-Path $defaultPublishSettings.LocalInstallDir 'publish-module.psm1'
if(Test-Path $localpublishmodulepath){
'importing module [publish-module="{0}"] from local install dir' -f $localpublishmodulepath | Write-Verbose
Import-Module $localpublishmodulepath -DisableNameChecking -Force
$true
}
}
}
}
try{
if (!(Enable-PublishModule)){
Enable-PackageDownloader
Enable-NuGetModule -name 'publish-module' -version $publishModuleVersion -nugetUrl $nugetUrl
}
'Calling Publish-AspNet' | Write-Verbose
# call Publish-AspNet to perform the publish operation
Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput
}
catch{
"An error occurred during publish.`n{0}" -f $_.Exception.Message | Write-Error
}' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
at System.Management.Automation.Runspaces.AsyncResult.EndInvoke()
at System.Management.Automation.PowerShell.EndInvoke(IAsyncResult asyncResult)
at Microsoft.Web.Publishing.Tasks.InvokePowerShell.Execute()
at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext() WebApplication1 0
I am assuming I missed something in my install? Anyone know what this error is or how to get passed it?
I upvoted this in the past, then apparently found the answer somewhere else, then forgot the answer again and ended up here again.
Adding <AutoParameterizationWebConfigConnectionStrings>False</AutoParameterizationWebConfigConnectionStrings>
in the csproj on the right PropertyGroup fixed the problem for me.

How can I have a Windows Service, installed using OctopusDeploy, use an app.config?

So far, I've been able to create a Windows Service, which I can then get TeamCity to build and pack up and make available for Octopus Deploy.
What I can't seem to do, is have an app.config which has a connection string in it and use that connection string.
The following is my Deploy.ps1:
# These variables should be set via the Octopus web portal:
#
# ServiceName - Name of the Windows service
#
# sc.exe is the Service Control utility in Windows
# Default the service name
if (! $ServiceName)
{
$ServiceName = "OctoService"
}
Write-Host "Service Name:" $ServiceName
# Get the exe name based ont the directory
$contentPath = (Join-Path $OctopusPackageDirectoryPath "content")
$configName = (Get-ChildItem $contentPath\*.config -Name | Select-Object -First 1)
$binPath = (Join-Path $OctopusPackageDirectoryPath "lib\net40")
$exeName = (Get-ChildItem $binPath\*.exe -Name | Select-Object -First 1)
$fullPath = (Join-Path $binPath $exeName)
Write-Host "Service Path:" $fullPath
Write-Host "Config Path:" (Join-Path $contentPath $configName)
Copy-Item (Join-Path $contentPath $configName) $binPath
$service = Get-Service $ServiceName -ErrorAction SilentlyContinue
if (! $service)
{
Write-Host "The service will be installed"
New-Service -Name $ServiceName -BinaryPathName $fullPath -StartupType Automatic
}
else
{
Stop-Service $ServiceName -Force
$fullPath = Resolve-Path $fullPath
& "sc.exe" config "$ServiceName" binPath= $fullPath start= auto | Write-Host
Start-Service $ServiceName
}
Here's my .nuspec file:
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>$id$</id>
<version>$version$</version>
<title>$title$</title>
<authors>$author$</authors>
<owners>$author$</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>$description$</description>
<copyright>Copyright 2012</copyright>
</metadata>
<files>
<file src="app.config" target="content" />
<file src="Deploy.ps1" />
</files>
</package>
If I try to access ConfigurationManager.ConnectionStrings["MyConnectionString"], I'll get a null reference.
Any suggestions?
my money is on you needing to name your app.config to exename.exe.config so it is picked up by your service.
App.config is the 'temporary' name used in the ide, it gets renamed as part of the build to whatever the exe name is

How to use an enum type in powershell when configuring IIS using the powershell snapin

I am using the IIS Powershell snapin to configure a new web application from scratch. I am new to PS. The following script will not workl as PS is not recognising the ManagedPipelineMode enum. If I change the value to 0 it will work. How can I get PS to understand th enum. I tried the Add-Type cmdlet and also load the Microsoft.Web.Administration assembly without any scuccess, these lines are now commented.
How can I get this PS script working with the enum ?
#Add-Type -AssemblyName Microsoft.Web.Administration
#[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Web.Administration")
Import-Module WebAdministration
$AppPoolName = 'Test AppPool'
if ((Test-Path IIS:\apppools\$AppPoolName) -eq $false) {
Write-Output 'Creating new app pool ...'
New-WebAppPool -Name $AppPoolName
$AppPool = Get-ChildItem iis:\apppools | where { $_.Name -eq $AppPoolName}
$AppPool.Stop()
$AppPool | Set-ItemProperty -Name "managedRuntimeVersion" -Value "v4.0"
$AppPool | Set-ItemProperty -Name "managedPipelineMode" -Value [Microsoft.Web.Administration.ManagedPipelineMode]::Integrated
$AppPool.Start()
}
The error message is:
Set-ItemProperty : [Microsoft.Web.Administration.ManagedPipelineMode]::Integrated is not a valid value for Int32.
It is expecting an integer, even though the underlying property is of type ManagaedPipelineMode. You can do below however:
$AppPool | Set-ItemProperty -Name "managedPipelineMode" -Value ([int] [Microsoft.Web.Administration.ManagedPipelineMode]::Classic)
PS:
Instead of
$AppPool = Get-ChildItem iis:\apppools | where { $_.Name -eq $AppPoolName}
you can do:
$AppPool = Get-Item iis:\apppools\$AppPoolName
Regarding: Add-Type -AssemblyName - this will only work for a canned set of assemblies that PowwerShell knows about. You have to find the assembly in your file system and use the -Path parameter. This worked on my system in a 64-bit PowerShell console:
Add-Type -Path C:\Windows\System32\inetsrv\Microsoft.Web.Administration.dll
Instead of using:
$AppPool | Set-ItemProperty -Name "managedPipelineMode" `
-Value [Microsoft.Web.Administration.ManagedPipelineMode]::Integrated
use:
$AppPool | Set-ItemProperty -Name "managedPipelineMode" `
-Value ([Microsoft.Web.Administration.ManagedPipelineMode]::Integrated)
or the even more succinct:
$AppPool | Set-ItemProperty -Name "managedPipelineMode" -Value Integrated
Why? The reason you need brackets in the first answer is because the parameter binder is treating the entire [Microsoft.Web.Administration.ManagedPipelineMode]::Integrated in your attempt as a string, which cannot be cast to that enumerated type. However, Integrated can be to that enum. By wrapping it in brackets, it is evaluated again as an expression and is treated as a full type literal.

How Do You Iterate Authentication for App IIS7 In PowerShell

I need to iterate all authentication modes for an IIS Application and disable all except one.
something like:
foreach($itm in [collection of authentication modes for app]){
if([certain authentication]){enabled = true}else{enabled = false}}
I'm familiar with Set-WebConfigurationProperty.
You can iterate all native (as well as any installed third-party) authentication modes for the root web application for a given site by calling Get-WebConfiguration:
$siteName = "MySiteName"
$authentications = Get-WebConfiguration `
-filter "system.webServer/security/authentication/*" `
-PSPath "IIS:\Sites\$siteName"
You can also iterate the authentication modes for any given web application in the site (or even specific file(s)). The following retrieves the authentication modes for a contrived web application called "\foo":
$authentications = Get-WebConfiguration `
-filter "system.webServer/security/authentication/*" `
-PSPath "IIS:\Sites\$siteName\foo"
The SectionPath property can be used to examine the authentication mode, e.g.:
$authentications | foreach {$_.SectionPath}
Which outputs:
/system.webServer/security/authentication/digestAuthentication
/system.webServer/security/authentication/anonymousAuthentication
/system.webServer/security/authentication/iisClientCertificateMappingAuthentication
/system.webServer/security/authentication/basicAuthentication
/system.webServer/security/authentication/clientCertificateMappingAuthentication
/system.webServer/security/authentication/windowsAuthentication
You might think you could do something as simple as this in your foreach loop...
$authentications | `
foreach { $_.Enabled = $_.SectionPath.EndsWith('\windowsAuthentication') }
...but there's a problem. It doesn't work. It won't actually fail with an error, but it won't change anything either.
That's because authentication sections are locked. To change a setting in a locked section, you need to call Set-WebConfigurationProperty and include the -Location parameter, e.g.,
Set-WebConfigurationProperty `
-filter "/system.webServer/security/authentication/windowsAuthentication" `
-name enabled -value true -PSPath "IIS:\" -location $siteName
I suppose you can still pipe the objects to the foreach-object cmdlet but it's probably going to be a lot easier to read (and maintain) if you script this using a foreach loop.
$siteName = "MySiteName"
$authentications = Get-WebConfiguration `
-filter "system.webServer/security/authentication/*" `
-PSPath "IIS:\Sites\$siteName"
foreach ($auth in $authentications)
{
$auth.SectionPath -match "/windowsAuthentication$"
$enable = ($matches.count -gt 0)
Set-WebConfigurationProperty `
-filter $auth.SectionPath `
-name enabled -value $enable -PSPath "IIS:\" -location $siteName
}

Resources