Showing posts with label vbscript. Show all posts
Showing posts with label vbscript. Show all posts

Friday, August 20, 2010

Active Directory SPOF

We had a great example of an AD SPOF (single point of failure) recently.  A vbscript had been written by someone with no malicious intent to (for some reason) hook into AD and check service accounts.  What this script ended up doing though was locking out said service accounts.  Within the span of 30 minutes we were well on our way to locking out 400+ service accounts in the enterprise, irrespective of environment.  This took production out of commission.
Seems like a bit of a hole to me.

Monday, July 12, 2010

.Net Self Serve Automated deploy

There are a couple of prerequisites that need to be in place in order for a self serve automated deployment system to work.
1. You should have a Nant, MsBuild, Visual Build, or a similar type of scripting file that is doing deploys for you already - see my previous posts on doing that here
2. Your folder structure for every project you want to deploy should be similar. To have a good Self-Serve Deploy tool, it needs to work on the assumption that directory structures are consistent for certain types of projects. This could be set up using your repository tags directory, or automatically copying deployment files to the required folder structure after the build is successful. A folder structure I've used in the past is b:\deployment\projectname\version\ My build file(s).  Any other required folders and files reside in the version folder with a consistent folder structure.
3. You need either a properties file or a DB table to manage which tag/version has been deployed to which environment. We've used a symlink in the past to denote the current 'tip' build. This example will use a file. The file is structured like:

<versions>
   <serverType>
       <server name="blahboxType" version="1.2" />
       <server name="fooboxType" version="1.0" />
   </serverType>
   <blahboxType>
       <project name="MyProject" version="3.1.0.23" />
       <project name="MyProject2" version="3.1.4.11" />
   </blahboxType>
   <fooboxType>
      <project name="fooProj1" version="6.2.123"/>
      <project name="fooProj2" version="6.3.92"/>
   </fooboxType>
</versions>

Once the deploy is finished to a particular environment, logic in the deployment file automatically updates the respective project in the appropriate version file.

Here's a bit of sample code for a client side asp page for a Self Serve app.  It passes some values to a server side asp page (deploy.asp) so that page will know which version of which project to deploy into which environment.  The onchange event of the env select control called an AJAX function that retrieves the currently deployed version of the project from the versions.xml file. 

<form action="deploy.asp" method="get" name="MyProject">
  <input name="project" type="hidden" value="MyProject" />
  <input name="serverType" type="hidden" value="blahboxType" />
  <select name="version">
     <option value="">--Select--</option>
     <option value="" & version & "">" & version & "</option>
  </select>

<select id="MyProject" name="env" onchange="getVersions('MyProject',this.value)">
    <option value="">--Select--</option>
    <option value="Test1">Test 1</option>
    <option value="Test2">Test 2</option>
    <option value="SB">Sandbox</option>
    <option value="STG">Staging</option>
    <option value="PRD">Production</option>
</select>

<div id="MyProjecttarget" style="color: green;">
-</div>

<input type="submit" value="Deploy" />
</form>

Then on my deploy.asp page, the request parameters are set to variables which are then used to dynamically build the path to the deploy file (in this case a visual build file called Deploy-<serverName>-<component>.bld)  This could be a nant, msbuild, or ant file as well, you'd just have to change which executable you're using in the executeString.  The command is then executed in a Windows Shell and if it has a return code of '0' it was successful.  Successful or not, we do some very simple logging to show who tried to deploy what, where, and when.
Here's the code:

 ' need a longer server timeout setting so our deploy can finish
     Server.ScriptTimeout=1200
'instantiate some vars
    env = ""
    version = ""
    project = ""
    severType = ""
   
'set the vars
    set version = Request.queryString("version")
    set env = Request.queryString("env")
    set project = Request.queryString("project")
    set serverType = Request.queryString("serverType")

    'gets the user
    Set WSHNetwork = CreateObject("WScript.Network")
    user = WSHNetwork.UserName

    if version="" then
        Response.Write("Please ensure you chose a version <br/>")
    elseif env="" then
        Response.Write("Please ensure you chose an environment")
    elseif project="" then
        Response.Write("error occured - project required")
    elseif LCase(env)="PRD" then
        Response.Write("We don't want to deploy to Production from this app")
    else

        Response.Write(version & " " & env & " " & project)
'set up a dynamic path here to the deployment file (nant or ant or visual build file)  This string assumes the
'build file is taking a parameter called Env - the environment to deploy to
        execString = "<pathToVisualBuildExecutable>\VisBuildCmd.exe /b " & Chr(34) & version & "\visual build\Deploy-" & serverType & "-" & component & ".bld" & Chr(34) & " Env=" & env

        Response.Write("<br/>" & executeString)

        set oFs = server.createobject("Scripting.FileSystemObject")
            set oTextFile = oFs.OpenTextFile("<pathOfFileToLogTo>\deploylog.txt", 8, True)
   
        Dim WshShell
        Set WshShell = CreateObject("WScript.Shell")
        proc = WshShell.Run(executeString,6,true)

        if proc="0" then
            response.write("<br/><br/><div style='color:green;font-size:16px;'>Deploy of build " & component & " " & version & " to " & env & " as " & user & " was successful")

            dt = now()
            logtext = dt & ":  Deploy of build " & component & " " & version & " to " & env & " was successful" & vbCrLf
            oTextFile.Write logtext
            oTextFile.Close
        else
            response.write("<br/><br/><div style='color:red;font-size:16px;'>Deploy of build " + component + " " + version + " to " + env + " failed using user " + user)
            dt = now()
            logtext = dt & ":  Deploy of build " & component & " " & version & " to " & env & " failed as user " & user & vbCrLf
            oTextFile.Write logtext
            oTextFile.Close
        end if

        response.write("<br/>Deploy times and results are logged at <pathOfFileToLogTo>\deploylog.txt")

        set oTextFile = nothing
        set oFS = nothing
        set WshShell=nothing

    end if
        response.write("<br/><a href='javascript:history.back()'>Back to deploy page<a/>")

Friday, August 14, 2009

XML manipulation in Visual Build (and vbscript)

We've been working on basically turning our Visual Build deployment files into DRP (Disaster Recovery Plan) scripts. Essentially, everything required to get our applications running on a 'blank' server box is documented as a config, permission, or push in our Visual Build files. This has required updating then machine.config and web.config files that reside under windows/microsoft.net/framework/v1.1.4322 or v2.0.50727/config at times. Sometimes we're adding attributes to existing element, sometimes we're adding entirely new elements.

It seems to me that adding entirely new elements in Visual Build (using the Write XML Action) has a bug in it. It will add new attributes to existing elements no problem. But it won't add new elements. So we hacked around that and used the 'Run Script' Action with vbscript to add elements to our files. To do this in vbscript it looks something like this:

Dim objXMLDoc, objNewNode, objText, strXPath, objParentNode, objChildNode, objCaseExist

Set objXMLDoc = CreateObject("Microsoft.XMLDOM")
objXMLDoc.async = False

' load the XML file - make sure to include the fully qualified path
fSuccess = objXMLDoc.load("\\%TARGET_SERVER%\c$\WINDOWS\Microsoft.NET\framework\v2.0.50727\config\web.config")
If Not fSuccess Then
wscript.echo ("error loading XML file")
Else
wscript.echo ("XML file loaded")
End If

' set to proper node
Set nodeList = objXMLDoc.getElementsByTagName("configuration/system.web/compilation/buildProviders")
If nodeList.length > 0 Then

Set objParentNode = nodeList(0)

' add the SGAS SecurityDisabled element/node
Set objNewNode = objXMLDoc.createElement("add")
objNewNode.setAttribute "extension", ".uplx"
objNewNode.setAttribute "type", "System.Web.Compilation.PageBuildProvider"
objParentNode.appendChild(objNewNode)
objParentNode.appendChild objXMLDoc.createTextNode (vbCrLf)

set objNewNode = Nothing

else

wscript.echo ("node list empty")

end if

' save the XML file
objXMLDoc.save("\\%TARGET_SERVER%\c$\WINDOWS\Microsoft.NET\framework\v2.0.50727\config\web.config")