Showing posts with label Powershell. Show all posts
Showing posts with label Powershell. Show all posts

Wednesday, May 14, 2014

PowerShell Copy-Item Recursion

I ran into something interesting today when doing a recursive copy in PowerShell. The “*” character makes a huge difference when you are copying to an existing directory with files.

For example, if I have a d:\temp\files directory that I want to copy to d:\temp\files2, I can do so by doing:

copy-item d:\temp\files d:\temp\files2 –recurse –force

However, run that same line again after changing a file or two and though it appears to copy, it won’t actually copy the files. In order for this to happen, you must include a * at the end of the path:

copy-item d:\temp\files\* d:\temp\files2 –recurse –force

Monday, April 9, 2012

Setting up a new IIS Server for ASP.NET or MVC

When setting up a new Windows Server for hosting ASP.NET or MVC applications, I have several Powershell scripts that I run to modify some of the default IIS settings.  You can also modify the IIS settings manually, but don’t fear the command line – it is your friend.

Powershell has an IIS module that you will need to import to run most of these commands – WebAdministration.  Now for the first set of scripts:
Import-Module WebAdministration
 
#expire web content after 30 days
Set-WebConfigurationProperty -filter "/system.webServer/staticContent/clientCache" -name cacheControlMode -value "UseMaxAge"
Set-WebConfigurationProperty -filter "/system.webServer/staticContent/clientCache" -name cacheControlMaxAge -value "30.00:00:00"
 
# change logging to include two more properties
Set-WebConfigurationProperty -filter "/system.applicationHost/sites/siteDefaults/logFile" -name logExtFileFlags -value "Date, Time, ClientIP, UserName, ServerIP, Method, UriStem, UriQuery, HttpStatus, Win32Status, BytesSent, BytesRecv, TimeTaken, ServerPort, UserAgent, HttpSubStatus"
 
# change the IIS server's header value to from value -- applies to ENTIRE SERVER
$computer = gc env:computername
Set-WebConfiguration  -filter "/system.webServer/httpProtocol/customHeaders/add[@value='ASP.NET']/@name" -value "From"
Set-WebConfiguration  -filter "/system.webServer/httpProtocol/customHeaders/add[@name='From']/@value" -value $computer

The above scripts are mostly self-explanatory – adjusting logging, static caching, and making sure the HTTP header of the sites on the box will include the box name.  This is especially useful in load-balanced scenarios, when you need to troubleshoot an errant server.

The next script modifies IIS to allow anonymous and windows authentication to be set in the web.config of child applications.
# change the master IIS config file to allow override of anonymous and windows auth
[xml]$config = Get-Content C:\Windows\System32\inetsrv\config\applicationHost.config
$config.selectSingleNode("/configuration/configSections/sectionGroup[@name='system.webServer']/sectionGroup[@name='security']/sectionGroup[@name='authentication']/section[@name='anonymousAuthentication']").SetAttribute("overrideModeDefault", "Allow")
$config.selectSingleNode("/configuration/configSections/sectionGroup[@name='system.webServer']/sectionGroup[@name='security']/sectionGroup[@name='authentication']/section[@name='windowsAuthentication']").SetAttribute("overrideModeDefault", "Allow")
$config.Save("C:\Windows\System32\inetsrv\config\applicationHost.config")

By default IIS does not allow child applications to define their own authentication.  You can change a site’s security policy in the IIS manager, but this modifies the security settings in the applicationHost.config file instead of the web.config of the application.  You can allow the local site’s web.config to define this with the script below:

And finally, I prefer IIS to be clear of any default sites and application pools before I start adding my own, so I remove them (Warning: this will clear all sites and application pools from a server):
# RESET IIS environment
Remove-Item 'IIS:\AppPools\*' -Recurse
Remove-Item 'IIS:\Sites\*' -Recurse

Tuesday, April 3, 2012

Creating and Modifying MSMQ’s Using Powershell

There are a few Powershell functions that I have written and use to create and delete queues in MSMQ and to modify permissions on these queues.  At the end of the script there are a few examples on how to use the functions.
Clear-Host
[Reflection.Assembly]::LoadWithPartialName("System.Messaging")
  
function Create-Queue
{
    param
    (
        [Parameter(Mandatory=$true)]
        [string]$queueName,
        [switch]$isPrivate = $true,     
        [switch]$isTransactional = $false
    )
      
    $innerQueueName = $queueName
      
    if ($isPrivate)
    {
        $innerQueueName = ".\private$\"+$queueName
    }
    else
    {
        $innerQueueName = ".\"+$queueName
    }
      
    if (![System.Messaging.MessageQueue]::Exists($innerQueueName))
    {
        [System.Messaging.MessageQueue]::Create($innerQueueName, $isTransactional) 
        Write-Host "Created queue " $innerQueueName
    }
    return $innerQueueName
}
  
function Add-QueueUserPermission
{
    param
    (
        [Parameter(Mandatory=$true)]
        [string]$queuePath,
        [Parameter(Mandatory=$true)]
        [string]$user,
        [string]$fullControl = $false
    )
      
    $q = new-object System.Messaging.MessageQueue($queuePath)
      
        if ($fullControl -eq $true)
        {
            Write-Host "FullControl granted to "  $user
            $q.SetPermissions($User, [System.Messaging.MessageQueueAccessRights]::FullControl, [System.Messaging.AccessControlEntryType]::Allow) 
        }
        else
        {
            Write-Host "Restricted access granted to "  $user      
            $q.SetPermissions($User, [System.Messaging.MessageQueueAccessRights]::DeleteMessage, [System.Messaging.AccessControlEntryType]::Set) 
            $q.SetPermissions($User, [System.Messaging.MessageQueueAccessRights]::GenericWrite, [System.Messaging.AccessControlEntryType]::Allow) 
            $q.SetPermissions($User, [System.Messaging.MessageQueueAccessRights]::PeekMessage, [System.Messaging.AccessControlEntryType]::Allow) 
            $q.SetPermissions($User, [System.Messaging.MessageQueueAccessRights]::ReceiveJournalMessage, [System.Messaging.AccessControlEntryType]::Allow)
        }
      
      
}
  
function Delete-Queue
{
    param
    (
        [Parameter(Mandatory=$true)]
        [string]$queuePath
    )
      
    [System.Messaging.MessageQueue]::Delete($queuePath)
}
  
function Delete-Queues
{
    [System.Messaging.MessageQueue]::GetPrivateQueuesByMachine($Env:COMPUTERNAME) | ForEach-Object { Delete-Queue($_.Path) }
    [System.Messaging.MessageQueue]::GetPublicQueuesByMachine($Env:COMPUTERNAME) | ForEach-Object { Delete-Queue($_.Path) }
}
  
#########################################################################################################################
  
#examples
# creates a queue that is private but not transactional
#Create-Queue -queueName "My Queue" -isPrivate $true -isTransactional $false
  
# grants restricted access to the queue
#Add-QueueUserPermission -queuePath ".\private$\My Queue" -user 'domain\account'
  
# grants full control to the queue
#Add-QueueUserPermission -queuePath ".\private$\My Queue" -user 'domain\account' -fullControl

Tuesday, March 13, 2012

New Computer Modifications

Each time I get a new computer I find myself turning off certain services, uninstalling Windows features, and disabling certain components.  Windows 7’s default installation includes items such as: Tablet PC Components, Windows Media Center, Windows DVD Maker, Windows Media Player, and Windows Gadget Platform.  It also has System Restore and Hibernation enabled, neither of which I use.  The commands below are what I run to turn off or disable the above features (Run in an elevated Powershell command window):
Disable-ComputerRestore –drive "C:"
powercfg –H off
DISM /online /Disable-Feature /FeatureName:MediaCenter /FeatureName:TabletPCOC /FeatureName:WindowsGadgetPlatform /FeatureName:WindowsMediaPlayer /FeatureName:MediaPlayback
You will need to restart your computer after running the above, but after doing so, you'll have more free CPU cycles and memory. Enjoy!

Monday, February 20, 2012

TFS 2010, Build Definitions, and Powershell

I needed to get a list of build definitions from a TFS 2010 instance as we are planning to migrate to a new server and will not be moving the collection, but only the builds and source files inside the collection. The following Powershell scripts will list out the build definitions for a server:
clear-host

[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Build.Client")
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.WorkItemTracking.Client")


$tfsCollectionUrl = "http://{server}:8080/tfs/{collection}"
$server = new-object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection(New-Object Uri($tfsCollectionUrl))
$buildServer = $server.GetService([Microsoft.TeamFoundation.Build.Client.IBuildServer])
$workStore = $server.GetService([Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItemStore])

$workStore.Projects | ForEach-Object {
Write-Host ("Project: "+$_.Name)
$buildServer.QueryBuildDefinitions($_.Name) | select-object {$_.Name, $_.ContinuousIntegrationType} | format-table
}