Friday, August 27, 2010

trick POSH into modifying the security's username

Sometimes you have to find a way around things. When you get creds from POSH, it leaves a "/" in the username, so you cannot just pull out the username for use in something that is non-microsoft. Well you can trick it into modifying it by copying it out into a new object. I am not smart enough to figure this out, a coworker of mine did though. I give full credit to him for figuring this out, as we could not find anyone on the internet who had.
So the story is, I wanted to copy our subversion code repository from the REPO server over HTTPS to the local box to update the websites on it. We didn't want to put any passwords in the file, so we wanted to use the operator's MS domain username and password. It is important to note that our domain name has three letters, so we pull 4 out of the credentials. If your domain is more or less, you will have to pull out more or less.

#########################################################
#
# Script to copy Machine and Webconfigs from the ... repository to the local host.
#
# Created Aug 18, 2010
# Bryan Loveless 
#  Props to "Catatonic Prime" for figuring out the Creds object thing
#
#
# Requires Powershell 2.0
#
# Change your Execution policy to RemoteSigned if running locally
# by: Set-executionpolicy -executionpolicy RemoteSigned
#
#Prereqs: Run on local machine runnning as THE administrator.  (right click, run as)
#
#Caviots:  If the files dont seem to renew, make sure the repo on ... is updated
#          by running the svn update bat file in the root of C 
#   called "...." .
#   Also, if it doesnt run as a script, you can copy/paste into POSH cmd line.
#  
#
########################################################

#import the bitstransfer module to transfer files
Import-Module BitsTransfer

#get user credentials
Write-Host "use ... domain when logging in (123\ABC123)"
$Dirtycreds = Get-credential "123\USERNAME"

#clean up the username, as it doesnt want a / before the username
#one below only removes first character, need 4 removed to preserve domain in $DirtyCreds for later use
#$creds = New-Object -typeName 'System.Management.Automation.PSCredential' -ArgumentList $Dirtycreds.UserName.Remove(0,1),$Dirtycreds.Password
$creds = New-Object -typeName 'System.Management.Automation.PSCredential' -ArgumentList $Dirtycreds.UserName.Remove(0,4),$Dirtycreds.Password


#####refresh common components to update svn on ..., dont have to do if pulling from HTTPS
##$session1 New-PSSession -ComputerName servername.fully.qualified.here
##Invoke-Command -Session $session1 ""filethatcleansupSVN""
#Import-Module BitsTransfer

#set a timestamp to rename the file with, uses seconds so that it can be run more than once a minute
$timestamp = Get-Date -UFormat %Y%m%d%H%M%S

#set the path to the SVN server
$svnserver = "servername.fully.qualified.here"

#ask the user if they want a dev, test, prod, localhost config
$machinetype = Read-Host "What type of machine is this?  (dev, test, prod, localhost)"


#below compares to see what the user wanted, then changes the variable for the path accordingly
switch ($machinetype)
{
dev {$svnpath = "svn/projects/Configuration/Machine%20Configs/IIS7/2.0/Dev/"
$smbpath = "\\$svnserver\c$\Projects\Configuration\Machine Configs\IIS7\2.0\Dev"}
test {$svnpath = "svn/projects/Configuration/Machine%20Configs/IIS7/2.0/Test/" 
$smbpath = "\\$svnserver\c$\Projects\Configuration\Machine Configs\IIS7\2.0\Test"}
prod {$svnpath = "svn/projects/Configuration/Machine%20Configs/IIS7/2.0/Prod/" 
$smbpath = "\\$svnserver\c$\Projects\Configuration\Machine Configs\IIS7\2.0\Prod"}
localhost {$svnpath = "svn/projects/Configuration/Machine%20Configs/IIS7/2.0/localhost_developer/" 
$smbpath = "\\$svnserver\c$\Projects\Configuration\Machine Configs\IIS7\2.0\localhost_developer"}
default {  Write-Host "I dont know what you want. Close this and try again."
break }
}



#set the path to the .net directory on the local machine
$mypath = "C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG"

#rename the old files
rename-item -path "$mypath\web.config" -NewName web$timestamp.config 
rename-item -path "$mypath\machine.config" -NewName machine$timestamp.config 

#copy the files to the correct locations

#HTTPs method below 
start-bitstransfer -Authentication basic -Displayname "grabwconfig" -credential $creds -Source "https://$svnserver/$svnpath/web.config" -Destination $mypath\web.config 
start-bitstransfer -Authentication basic -Displayname "grabmconfig" -credential $creds -Source "https://$svnserver/$svnpath/machine.config" -Destination $mypath\machine.config 

#Below replaced by HTTPS method
#Copy-Item -Path "$smbpath/web.config" -Credential $creds -Destination "$mypath/web.Config"
#Copy-Item -Path "$smbpath/web.config" -Destination "$mypath/web.Config"
#Copy-Item -Path "$smbpath/machine.config" -Destination "$mypath/machine.Config"


# this will only do the part below if a 64 bit machine
$mypath = "C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG"
if (test-path $mypath)
{
#rename the old files
rename-item -path $mypath\web.config -NewName web$timestamp.config
rename-item -path $mypath\machine.config -NewName machine$timestamp.config

#below replaced by HTTPs method
# Copy-Item -Path "$smbpath/web.config" -Destination "$mypath/web.Config"
# Copy-Item -Path "$smbpath/machine.config" -Destination "$mypath/machine.Config"

#pull it from HTTPs
start-bitstransfer -Authentication basic -Displayname "grabw64config" -credential $creds -Source "https://$svnserver/$svnpath/web.config" -Destination $mypath\web.config 
start-bitstransfer -Authentication basic -Displayname "grabm64config" -credential $creds -Source "https://$svnserver/$svnpath/machine.config" -Destination $mypath\machine.config

}


#copy applicationhost.config to the correct location and rename the old one
$mypath = "C:\Windows\System32\inetsrv\config"
$smbpath = "\\$svnserver\c$\Projects\Configuration\Machine Configs\IIS7"
$svnpath = "svn/projects/Configuration/Machine Configs/IIS7/"
rename-item -path $mypath\applicationHost.config -NewName applicationHost$timestamp.config

start-bitstransfer -Authentication basic -Displayname "grabAHconfig" -credential $creds -Source "https://$svnserver/$svnpath/applicationHost.config" -Destination $mypath\applicationHost.config 

#below replaced by HTTPs method
#Copy-item -path $smbpath\applicationHost.config -Destination "$mypath/applicationHost.config"

fix NTFS permissions on website directories using POSH

#########################################################
#
# Script to Fix web NTFS permissions.
#
# Created Aug 23, 2010
# Bryan Loveless 
#
#
# Requires Powershell 2.0
#
# Change your Execution policy to RemoteSigned if running locally
# by: Set-executionpolicy -executionpolicy RemoteSigned
#
#Prereqs: 
#
#
#based on http://blog.netnerds.net/2007/07/powershell-set-acl-does-not-appear-to-work/
#
########################################################



#the correct permissions on All Tiers (edited) are FC:(usernames went here for documentation)
# RXLR: localmachine\IIS_IUSRS


$whorunsthis = Read-host "Is this a (S)erver (c:\otherplaceIhavethem) or your (L)ocal box (C:\intetorsomething\Websites)? (S/L)"
Write-Host "Also, this script will take a few minutes, give it some time."

if ($whorunsthis -eq "S" )
{$path = "c:\otherplaceIhavethem" }
elseif ($whorunsthis -eq "L")
{$path = "C:\intetorsomething\Websites" }
else
{write-host "you must select S or L" 
Exit}

$fullControlDomainFolks = "user1","abc123","edf456","anotherusername"
$fullControlLocalUsers = "system"
$readOnlyLocalUsers = "IIS_IUSRS"

#now to run through the list of users listed in the $fullControlDomainFolks list.
ForEach ($specificUser in $fullControlDomainFolks)
{
$user = $specificUser
$userdomain = "DomainName"
#set up inheritance to be turned on
$inherit = [system.security.accesscontrol.InheritanceFlags]"ContainerInherit, ObjectInherit"
#set up propagation
$propagation = [system.security.accesscontrol.PropagationFlags]"None"
#since get-acl only can deal with objects, we have to give it an object to start with.
$acl = Get-Acl $path

#setting what type of access we want the user to have.
#FYI, the possible values for $aclType are "ListDirectory, ReadData, WriteData, CreateFiles, CreateDirectories, AppendData, 
#ReadExtendedAttributes, WriteExtendedAttributes, Traverse, ExecuteFile, DeleteSubdirectoriesAndFiles, 
#ReadAttributes, WriteAttributes, Write, Delete, ReadPermissions, Read, ReadAndExecute, Modify, ChangePermissions, 
#TakeOwnership, Synchronize, FullControl".
$aclType = "FullControl"
#set up the access rule by creating a new object with the variables set above.
$accessrule = New-Object system.security.AccessControl.FileSystemAccessRule("$userdomain\$user", $aclType, $inherit, $propagation, "Allow")
#now to change the object we borrowed to what we actually want it to be
$acl.AddAccessRule($accessrule)
#now to actualy change the permissions on the path we specified.
set-acl -aclobject $acl $path
}

#now to run throught he list of users listed in the $fullcontrolLocalUsers list.
ForEach ($specificUser in $fullControlLocalUsers)
{
$user = $specificUser
#set up inheritance to be turned on
$inherit = [system.security.accesscontrol.InheritanceFlags]"ContainerInherit, ObjectInherit"
#set up propagation
$propagation = [system.security.accesscontrol.PropagationFlags]"None"
#since get-acl only can deal with objects, we have to give it an object to start with.
$acl = Get-Acl $path

#setting what type of access we want the user to have.
#FYI, the possible values for $aclType are "ListDirectory, ReadData, WriteData, CreateFiles, CreateDirectories, AppendData, 
#ReadExtendedAttributes, WriteExtendedAttributes, Traverse, ExecuteFile, DeleteSubdirectoriesAndFiles, 
#ReadAttributes, WriteAttributes, Write, Delete, ReadPermissions, Read, ReadAndExecute, Modify, ChangePermissions, 
#TakeOwnership, Synchronize, FullControl".
$aclType = "FullControl"
#set up the access rule by creating a new object with the variables set above.
$accessrule = New-Object system.security.AccessControl.FileSystemAccessRule("$user", $aclType, $inherit, $propagation, "Allow")
#now to change the object we borrowed to what we actually want it to be
$acl.AddAccessRule($accessrule)
#now to actualy change the permissions on the path we specified.
set-acl -aclobject $acl $path
}

#now to run throught he list of users listed in the $ReadOnlyLocalUsers list.
ForEach ($specificUser in $ReadOnlyLocalUsers)
{
$user = $specificUser
#set up inheritance to be turned on
$inherit = [system.security.accesscontrol.InheritanceFlags]"ContainerInherit, ObjectInherit"
#set up propagation
$propagation = [system.security.accesscontrol.PropagationFlags]"None"
#since get-acl only can deal with objects, we have to give it an object to start with.
$acl = Get-Acl $path

#setting what type of access we want the user to have.
#FYI, the possible values for $aclType are "ListDirectory, ReadData, WriteData, CreateFiles, CreateDirectories, AppendData, 
#ReadExtendedAttributes, WriteExtendedAttributes, Traverse, ExecuteFile, DeleteSubdirectoriesAndFiles, 
#ReadAttributes, WriteAttributes, Write, Delete, ReadPermissions, Read, ReadAndExecute, Modify, ChangePermissions, 
#TakeOwnership, Synchronize, FullControl".
$aclType = "ReadAndExecute"
#set up the access rule by creating a new object with the variables set above.
$accessrule = New-Object system.security.AccessControl.FileSystemAccessRule("$user", $aclType, $inherit, $propagation, "Allow")
#now to change the object we borrowed to what we actually want it to be
$acl.AddAccessRule($accessrule)
#now to actualy change the permissions on the path we specified.
set-acl -aclobject $acl $path
}

create a bunch of websites using POSH

#########################################################
#
# Script to Create the websites in all tiers.
#
# Created Aug 20, 2010
# Bryan Loveless 
#
#
# Requires Powershell 2.0
#
# Change your Execution policy to RemoteSigned if running locally
# by: Set-executionpolicy -executionpolicy RemoteSigned
#
#Prereqs: Have physical paths created already.  
#    Also must have at least one site that exists.  Keep the "Default" 
#        one for now.
#
########################################################
import-module webadministration

$physicalpath = "C:\Projects\Websites" 

#New-Item iis:\Sites\$sitename -bindings @{protocol="http";bindingInformation=":80:$sitename"} -physicalPath $physicalpath\$sitename

#list all websites below, IIS names are same as Physical Paths ON PURPOSE!

$listofwebsites = "site1","site2","site3","YouGetTheIdeaRight","wehavelotsmore","butforthisblog","IshortendTheList"

foreach ($site in $listofwebsites)
{
#create the site, associate with physical path. WILL OVERWRITE OLD SITE!
New-Item iis:\Sites\$site -bindings @{protocol="http";bindingInformation="*:80:"} -physicalPath $physicalpath\$site -Force

#Adds the HTTPS port to all sites.

New-WebBinding -Name "$site" -IP "*" -Port 443 -Protocol https

#stop the site after creating it
Stop-Website $site
}

# to see what a site has, try:
# get-webbinding -name "NAMEOFSITE"

Convert an IIS cert to an apache one

Here is a simple powershell script I wrote to convert a "iis" cert to one that apache is happy with to use with SSL:

####################################################


#convert IIS certs to openSSL ones for Apache to use
# openssl is installed with Apache by default.
#
#created May 24, 2010
#Bryan Loveless 
#
#

Write-host "This script assumes you have openssl installed in the C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin Directory 
And your certs are in the C:\Program Files (x86)\Apache Software Foundation\Apache2.2\certs Directory"


####################################################

Set-Location "C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin"

$OrgCert=Read-Host "What is the name of your cert? (Include the .pfx)"

$NewCert= Read-Host "What do you want to name the new one? (Include the .pem) Normally it is apache.key.pem"

$NewKey= Read-Host "What do you want to name the new one? (Include the .key) Normally it is apache.key"

$newkey2= Read-Host "What do you want to name the new one? (Include the .pem) Normally it is apache.cert.pem"

#PS C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin> 

.\openssl.exe pkcs12 -in ..\certs\$OrgCert -nocerts -out ..\certs\$NewCert -nodes

#Enter Import Password:
#MAC verified OK
#Enter PEM pass phrase:
#Verifying - Enter PEM pass phrase:

#PS C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin> 
.\openssl.exe pkcs12 -in ..\certs\$OrgCert -clcerts -nokeys -out $newkey2
#Enter Import Password:
#PS C:\Program Files (x86)\Apache Software Foundation\Apache2.2\bin> 
.\openssl.exe rsa -in ..\certs\$NewCert -out ..\certs\$NewKey
#Enter pass phrase for ..\certs\apache.key.pem:
#writing RSA key
 for converting the chain 
#OpenSSL Convert P7B
#
#Convert P7B to PEM
#
#openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer
#
#Convert P7B to PFX
#
#openssl pkcs7 -print_certs -in certificate.p7b -out certificate.cer
#
#openssl pkcs12 -export -in certificate.cer -inkey privateKey.key -out certificate.pfx -certfile CACert.cer
#OpenSSL Convert PFX
#
#Convert PFX to PEM
#
#openssl pkcs12 -in certificate.pfx -out certificate.cer -nodes

Intro

With being an IT guy, sometimes it is easy to Google your way out of a problem.  Sometimes you may be the first one to discover something.  Sometimes you are not the first person to discover something, but the first to put the solution on the internet.  This blog is to possibly help someone else out with a problem I faced that I have solved.  Sometimes this may not just be about work though.  After all, the internet is supposed to know everything, right?  Lets help it out a bit.