Thursday, March 26, 2015

Automate generation of credentials for service accounts


<#
    .SINOPSIS
        Generate credentials for service accounts.

    .DESCRIPTION
        Uses a login name list to generate a password for each login and export credentials to csv file,
        that can be imported into Keepass.
        Author: Antonio Sotelo
        Email:

    .EXAMPLE
        loginnames.txt contains login names for the service accounts,
        the script generate a password for each login name and export credentials to csv file.
        .\Create-CSVFile -loginsFile "c:\loginnames.txt" -csvFile "c:\SvcAccounts.csv" -verbose

    .LINKS
         References:

         How to export data to CSV in PowerShell?
         http://stackoverflow.com/questions/21047185/how-to-export-data-to-csv-in-powershell

         Generate a random and complex passwords
         https://gallery.technet.microsoft.com/scriptcenter/Generate-a-random-and-5c879ed5

    .NOTES
        Use KeePass 2.28 to import csv file using Generic CSV Importer.
        Then you can export from it and import to Keepass 1.28

#>

[CmdletBinding()]
Param (
    [Parameter(Mandatory=$false)]
    [string]$csvFile = "c:\SvcAccounts.csv",
    [string]$loginsFile = "loginnames.txt"


)

#Load password generator function
. .\New-SWRandomPassword.ps1
$Accounts = Get-Content $loginsFile
$results = @()
Write-Verbose "Generating passwords for each user in the list."
foreach ($Account in $Accounts) {
        Write-Verbose "Generating password for $Account"
        $Password = New-SWRandomPassword -MinPasswordLength 16 -MaxPasswordLength 16

        $Credentials = @{            
                           
               'Login Name'   = $Account                
                Password      = $Password
        }                           
        $results += New-Object PSObject -Property $Credentials  
  
}
Write-Verbose "Finished generating passwords, exporting credentials to $csvFile file."
$results | export-csv -Path $csvFile -NoTypeInformation

Thursday, March 19, 2015

Automating Windows patching for VM templates



# This script will convert template to VM, Power On VM, run Windows Update remotely, reboot VMGuest, shut VM down and finally convert back to template
# From https://communities.vmware.com/message/2470778
# Modified by Antonio Sotelo

# Requires Windows Update PowerShell Module installed on the template to run Get-WUInstall cmdlet.
# https://gallery.technet.microsoft.com/scriptcenter/2d191bcd-3308-4edd-9de2-88dff796b0bc/file/41459/43/PSWindowsUpdate.zip
# Extract to %WINDIR%\System32\WindowsPowerShell\v1.0\Modules

# Connect to vCenter
# http://blogs.vmware.com/PowerCLI/2013/03/back-to-basics-connecting-to-vcenter-or-a-vsphere-host.html
# Get the Credentials (Using VICredentialStore "C:\Scripts\vicredentials.xml" is created running the PowerCLI  console as the user account that runs the scheduled task.
# Example of scheduled task command: 
#   powershell.exe -PSconsolefile "c:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\vim.psc1" "& 'C:\Scripts\PatchVMTemplates.ps1'"
#   Scheduled to run second Tuesday of the month

$vicreds = Get-VICredentialStoreItem -file  "C:\Scripts\vicredentials.xml"

Connect-VIServer $vicreds.host -User $vicreds.User -Password $vicreds.Password


Function PatchVMTemplate ($VMTemplate){
# Convert template to VM
Set-Template -Template $VMTemplate -ToVM -Confirm:$false -RunAsync
Start-sleep -s 30

# Start VM template
# Thanks to http://theboywonder.co.uk/2012/10/19/catching-virtual-machine-questions-with-powercli/
try
{
    try
    {
        Start-VM -VM $VMTemplate -ErrorAction Stop -ErrorVariable custErr
    }
    catch [System.Management.Automation.ActionPreferenceStopException]
    {
        throw $_.Exception
    }
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.VMBlockedByQuestionException]
{
        Get-VMQuestion -VM $VMTemplate | Set-VMQuestion –Option "I copied it" -Confirm:$false 
}

Start-sleep -s 120
 
# Create variables for Guest OS credentials - This is needed for the Invoke-VMScript cmdlet to be able to execute actions inside the Guest.
$Username = "administrator"
# Note: Password is encrypted in OSPwd.txt which needs to be created beforehand using this command: read-host -assecurestring | convertfrom-securestring | out-file C:\Scripts\OSPwd.txt
# This file is created running the PowerCLI console as the user account that runs the scheduled task.
$OSPwd = cat C:\Scripts\OSPwd1.txt | convertto-securestring
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $Username, $OSPwd

# The following is the cmdlet that will invoke the Get-WUInstall inside the GuestVM to install all available Windows updates.
# Requires Windows Update PowerShell Module installed on the template to run Get-WUInstall cmdlet.
# Results are exported to a log file to see the patches installed and related results.
Invoke-VMScript -ScriptType PowerShell -ScriptText "Get-WUInstall –WindowsUpdate –AcceptAll –AutoReboot" -VM $VMTemplate -GuestCredential $Cred | Out-file -Filepath C:\$VMTemplate-WUResults.log # -Append
 
Start-sleep -s 120
 
# Restart VMGuest one more time in case Windows Update requires it and for whatever reason the –AutoReboot switch didn’t complete it.
Restart-VMGuest -VM $VMTemplate -Confirm:$false
 
Start-sleep -s 300

# Shutdown the server and convert it back to Template.
Shutdown-VMGuest $VMTemplate -Confirm:$false
Start-sleep -s 120
Set-VM –VM $VMTemplate -ToTemplate -Confirm:$false

} #End of Function

PatchVMTemplate "Test_Template"


# Send an email with WU Results
$EmailTo = "admin@somewhere.com"
$EmailSubject = "WSUS Patching for VM Templates"
  Send-MailMessage -To $EmailTo `
  -Subject $EmailSubject -From "WSUSReporting@somewhere.com" `
  -Body "VM templates have been patched. See attachments for details. This is an automated message. Do not reply to this email." `
  -Attachments "C:\Test_Template-WUResults.log"
  -SmtpServer "mail.smtpserver.com"



Changing Application Pool's CPU settings.


<#
     .SYNOPSIS
        Change Application Pool's CPU settings.

     .DESCRIPTION
        Sets CPU Limit(percent) to 80% and CPU Limit Action to "Throttle Under Load"
        for all application pools on Windows 2012+

     .PARAMETER ApplicationPoolName
        Name of the Application Pool.

     .LINK
        References:
        http://www.iis.net/learn/manage/powershell/powershell-snap-in-making-simple-configuration-changes-to-web-sites-and-application-pools
        http://stackoverflow.com/questions/11187304/how-to-set-iis-applicationpool-private-memory-limit-value-using-powershell
     
     .NOTES
        Author: Antonio Sotelo
        Email: 

     .EXAMPLE
        Set-AppPoolCPUDefaults -Verbose
        Changes default app pool's cpu settings to cpu= 80% and cpu action= throttle under load.

        Set-CPUSettings -ApplicationPoolName DefaultAppPool -Verbose -verbose
        Changes all app pool's cpu settings to cpu= 80% and cpu action= throttle under load.
#>


Function Set-AppPoolCPUDefaults () {
[cmdletbinding()]
    param (
    [Parameter( Mandatory=$False)]
        [int]$Percent = 80000,
    [Parameter( Mandatory=$False)]
        [string]$Action = "ThrottleUnderLoad"   
                
    )

    Set-WebConfiguration -filter '/system.applicationHost/applicationPools/applicationPoolDefaults/cpu/@limit' -PSPath IIS:\ -value $Percent
    Set-WebConfiguration -filter '/system.applicationHost/applicationPools/applicationPoolDefaults/cpu/@action' -PSPath IIS:\ -value $Action

    Write-Verbose "Default CPU Limit = $((Get-WebConfiguration /system.applicationHost/applicationPools/applicationPoolDefaults).cpu.limit)"
    Write-Verbose "Default CPU Action = $((Get-WebConfiguration /system.applicationHost/applicationPools/applicationPoolDefaults).cpu.action)"

}#End of function

Function Set-CPUSettings (){
[cmdletbinding()]
    param (
    [Parameter( Mandatory=$False)]
        [string]$ApplicationPoolName,

    [Parameter( Mandatory=$False)]
        [int]$Percent = 80000,
    [Parameter( Mandatory=$False)]
        [string]$Action = "ThrottleUnderLoad"   
                
    )

    Set-ItemProperty IIS:\AppPools\$ApplicationPoolName -Name cpu -Value @{limit=$Percent;action=$Action}
    $cpuLimit = (Get-ItemProperty IIS:\AppPools\$ApplicationPoolName -Name cpu).limit
    $cpuAction = (Get-ItemProperty IIS:\AppPools\$ApplicationPoolName -Name cpu).action
    Write-Verbose "$ApplicationPoolName CPU settings: CPU limit = $cpuLimit , CPU action = $cpuAction"

}#End of function

Write-Output "Changing Application Pool Default CPU settings."
Set-AppPoolCPUDefaults -Verbose

Write-Output "Changing CPU settings for all Application Pools on $env:ComputerName "

get-item IIS:\AppPools\* | %{

Set-CPUSettings -ApplicationPoolName $_.name -Verbose

}