Thursday, February 28, 2013

VBScript for compressing files in a folder and send on FTP

This is a simple vbscript compression script. works flawlessly on text files even bigger than 15GB.
We have a SSIS data generation package installed on our DB server which generates huge data files for data mining operations for current year, current month. The below scripts are doing the rest; compress the files and FTP to the data mining server location.
 
'======================================================
' Function : Zip datamart CSV, CTL files to local server for archive purposes.
'======================================================
Function WindowsZip(sFile, sZipFile, szPath, szDate)
  Set oZipShell = CreateObject("WScript.Shell") 
  Set oZipFSO = CreateObject("Scripting.FileSystemObject")
  Set LogFile = oZipFSO.CreateTextFile(szPath & "\Logs\log_" & szDate & ".log", true) 
 LogFile.WriteLine("=======================================")
  LogFile.WriteLine(Now & " - Compressing CSV file - Starting...")
 LogFile.WriteLine("=======================================")
  If Not oZipFSO.FileExists(sZipFile) Then
    NewZip(sZipFile)
  End If
  Set oZipApp = CreateObject("Shell.Application")
  Set source = oZipApp.NameSpace(sFile).Items
  sZipFileCount = oZipApp.NameSpace(sZipFile).items.Count
oZipApp.NameSpace(sZipFile).Copyhere source
LogFile.WriteLine(sZipFile & " - Compressing -")
'Keep script waiting until Compressing is done
On Error Resume Next
sLoop = 0
Do Until sZipFileCount < oZipApp.NameSpace(sZipFile).Items.Count
 Wscript.Sleep(100)
 sLoop = sLoop + 1
Loop
On Error GoTo 0
  LogFile.WriteLine(sZipFile & " - Successfully compressed -")
  LogFile.WriteBlankLines 1
  LogFile.Close
  Set LogFile = Nothing
  Set oZipShell = Nothing
  Set oZipFSO = Nothing 
End Function
Sub NewZip(sNewZip)
  Set oNewZipFSO = CreateObject("Scripting.FileSystemObject")
  Set oNewZipFile = oNewZipFSO.CreateTextFile(sNewZip)
  oNewZipFile.Write Chr(80) & Chr(75) & Chr(5) & Chr(6) & String(18, 0)
  oNewZipFile.Close
  Set oNewZipFSO = Nothing
  Wscript.Sleep(500)
End Sub
'======================================================
' Function : Upload datamart CSV, CTL files to MTMS FTP server.
'======================================================
Function FTPUpload(sSite, sUsername, sPassword, sLocalFile, sRemotePath, szPath, szDate, szYear, szMonth)
  Const OpenAsDefault = -2
  Const FailIfNotExist = 0
  Const ForReading = 1
  Const ForWriting = 2
  Set oFTPScriptFSO = CreateObject("Scripting.FileSystemObject")
  Set oFTPScriptShell = CreateObject("WScript.Shell")
  Set LogFile = oFTPScriptFSO.OpenTextFile(szPath & "\Logs\log_" & szDate & ".log", 8)  
LogFile.WriteLine("========================================")
  LogFile.WriteLine(Now & " - Sending CSV file on FTP - Starting...")
LogFile.WriteLine("========================================")
  sRemotePath = Trim(sRemotePath)
  sLocalFile = Trim(sLocalFile)  
  'Check to ensure that a remote path was
  'passed. If it's blank then pass a "\"
  If Len(sRemotePath) = 0 Then
    sRemotePath = "\"
  End If
  If InStr(sLocalFile, "*") Then
    If InStr(sLocalFile, " ") Then
      FTPUpload = "Error: Wildcard uploads do not work if the path contains a " & "space." & vbCRLF
      FTPUpload = FTPUpload & "This is a limitation of the Microsoft FTP client."
 LogFile.WriteLine(FTPUpload)
      Exit Function
    End If
  ElseIf Len(sLocalFile) = 0 Or Not oFTPScriptFSO.FileExists(sLocalFile) Then
    'nothing to upload
    FTPUpload = "Error: File Not Found."
LogFile.WriteLine(sLocalFile & FTPUpload)
    Exit Function
  End If
  '--------END Path Checks---------
  
  'build input file for ftp command
  sFTPScript = sFTPScript & "USER " & sUsername & vbCRLF
  sFTPScript = sFTPScript & sPassword & vbCRLF
  sFTPScript = sFTPScript & "prompt " & vbCRLF
  sFTPScript = sFTPScript & "cd " & sRemotePath & vbCRLF
  sFTPScript = sFTPScript & "binary" & vbCRLF
  sFTPScript = sFTPScript & "lcd " & szPath & vbCRLF
  sFTPScript = sFTPScript & "mput " & sLocalFile & vbCRLF
  sFTPScript = sFTPScript & "quit" & vbCRLF & "quit" & vbCRLF & "quit" & vbCRLF
  sFTPTemp = oFTPScriptShell.ExpandEnvironmentStrings("%TEMP%")
  sFTPTempFile = sFTPTemp & "\" & oFTPScriptFSO.GetTempName
  sFTPResults = sFTPTemp & "\" & oFTPScriptFSO.GetTempName

  'Write the input file for the ftp command
  'to a temporary file.
  Set fFTPScript = oFTPScriptFSO.CreateTextFile(sFTPTempFile, True)
  fFTPScript.WriteLine(sFTPScript)
  fFTPScript.Close
  Set fFTPScript = Nothing  
  oFTPScriptShell.Run "%comspec% /c FTP -n -s:" & sFTPTempFile & " " & sSite & " > " & sFTPResults, 0, TRUE
  Wscript.Sleep 1000
  'Check results of transfer.
  Set fFTPResults = oFTPScriptFSO.OpenTextFile(sFTPResults, ForReading, FailIfNotExist, OpenAsDefault)
  'sResults = fFTPResults.ReadAll
  Do Until fFTPResults.AtEndOfStream
    sResults = sResults & vbCRLF & fFTPResults.ReadLine
  Loop
  fFTPResults.Close
  oFTPScriptFSO.DeleteFile(sFTPTempFile)
  oFTPScriptFSO.DeleteFile (sFTPResults)
  If InStr(sResults, "226 Transfer complete.") > 0 Then
    FTPUpload = "226 Transfer complete."
  ElseIf InStr(sResults, "File not found") > 0 Then
    FTPUpload = "Error: File Not Found"
  ElseIf InStr(sResults, "cannot log in.") > 0 Then
    FTPUpload = "Error: Login Failed."
  Else
    FTPUpload = sResults & "Error: Unknown."
  End If
  LogFile.WriteLine(FTPUpload)
  LogFile.WriteBlankLines 1
  LogFile.Close
  Set oFTPScriptFSO = Nothing
  Set oFTPScriptShell = Nothing
  Set LogFile = Nothing
End Function

Dim dtTemp, szMonth, szDayName, szDay, szYear, inFilename, outFilename, szPath, szDate
dtTemp = Date
'Get the 2 digit month. VBScript does not include a function for this
if (len(CStr(Month(dtTemp))) < 2) then
szMonth = "0" & CStr(Month(dtTemp))
else
szMonth = CStr(Month(dtTemp))
end if
if (len(CStr(Day(dtTemp))) < 2) then
szDay = "0" & CStr(Day(dtTemp))
else
szDay = CStr(Day(dtTemp))
end if
szYear = Year(dtTemp)
szPath = "D:\FILES"
szDate = szYear & szMonth & szDay
inFilename = szPath & "\" & szYear & "\" & szMonth
outFilename = szPath & "\Archive\COMPRESSED" & ".ZIP"
Wscript.Echo WindowsZip(inFilename, outFilename, szPath, szDate)
 Wscript.Echo FTPUpload("xx.xx.xx.xx", "userid", "password", outFilename, "REMOTEPATH", szPath, szDate, szYear, szMonth)

Save the above script as compress_ftp.vbs, and run it on task scheduler with cscript. For the total file size around 20GB, this process will take around 1 hour. 

Sunday, November 11, 2012

VBScript for URL link creation


We had a need to create URL link of our project on users's desktop using a script. First stage the users had enough rights on their PC's so we included the required icon file also with the script and passed the following VBScript to users to click on it to create the desktop icon link.

' Definie shell object
Set objWSHShell = WScript.CreateObject("Wscript.Shell")
strDesktop = objWSHShell.SpecialFolders("Desktop")
' Copy the icon file to windows
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFileCopy = objFSO.GetFile( objWSHShell.CurrentDirectory&"\icon.ico")
objFileCopy.Copy ("C:\WINDOWS\system32\")
' Define link properties and create link
strShortcutName = "Log In" ' Shortcut Name - Edit for the wanted name
strShortcutPath = "http://thesystem.com/Login.aspx" ' Link URL - Edit to the wanted URL
strIconPath = "C:\WINDOWS\system32\icon.ico"
Set objShortcut = objWSHShell.CreateShortcut(strDesktop & "\" & strShortcutName & ".lnk")
objShortcut.TargetPath=strShortcutPath
objShortcut.IconLocation=strIconPath
objShortcut.Save

' Quit Script
WScript.Quit

But later the user access rights has been limited and were blocked accessing system folder, the link creator didn't created the link with supplied icon file. As the icon file is copied to the system folder. So the updated script would not use supplied icon file, but make use of existing system icon.

' Definie shell object
Set objWSHShell = WScript.CreateObject("Wscript.Shell")
strDesktop = objWSHShell.SpecialFolders("Desktop")

' Define link properties and create link
strShortcutName = "LogIn" ' Shortcut Name - Edit for the wanted name
strShortcutPath = "http://thesystem.com/Login.aspx" ' Link URL - Edit to the wanted URL
strIconPath = "c:\windows\system32\shell32.dll,44"
Set objShortcut = objWSHShell.CreateShortcut(strDesktop & "\" & strShortcutName & ".lnk")
objShortcut.TargetPath=strShortcutPath
objShortcut.IconLocation=strIconPath
objShortcut.Save

' Quit Script
WScript.Quit

Now the icon shown from system.

Friday, October 5, 2012

ASP.NET default Login page and controller modification for using with Web Service or local method

By default the ASP.NET login page and controls are bound with default methods and its bit uneasy to work with ( at least for some ppl like me). We could make use of same controller and pages with our own mechanism of logging in.

1. Changes on web.config

<location path="Login.aspx">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
  </location>
  <location path="Styles">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
  </location>
  <location path="Images">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
  </location>
  <system.web>
    <authorization>
      <deny users="?" />
    </authorization>
  </system.web>

2. Moving files
    Move the Login.aspx and related files outside the default folder and delete the folder
   

3. Update on Login frontend, add the onclick method

<p class="submitButton">
                    <asp:Button ID="LoginButton" runat="server" onclick="LoginButton_Click" Text="Log In" ValidationGroup="LoginUserValidationGroup"/>
                </p>

4. Update on Login backend

protected void LoginButton_Click(object sender, EventArgs e)
        {
            bool authSuccess = false;
            sc.AppCode = WebConfigurationManager.AppSettings["appCode"];
            sc.AppPwd = WebConfigurationManager.AppSettings["appPwd"];
            sc.ClientIP = "aa";
            sc.EndUserId = "aa";

            try
            {
                if (LoginUser.UserName == WebConfigurationManager.AppSettings["userId"]) // web.config user id
                {
                    if (LoginUser.Password == WebConfigurationManager.AppSettings["userPwd"])
                    {
                        authSuccess = true;
                    }
                    else 
                    {
                        authSuccess = false;
                    }
                }
                else // other user id
                {
                    req.ServiceContext = sc;
                    req.UserId = LoginUser.UserName;
                    req.UserPwd = LoginUser.Password;

                    try
                    {
                        response = port.Authenticate(req);
                        if(response.Status.ToUpper() == "OK")
                        {
                            authSuccess = true;
                        }
                        else
                        {
                            authSuccess = false;
                            wsStatus.Text = response.Message;
                        }

                    }
                    catch (Exception lex)
                    {
                        wsStatus.Text = lex.Message;
                        authSuccess = false;
                    }
                }

                //
                if (authSuccess)
                {
                    FormsAuthentication.SetAuthCookie(LoginUser.UserName, false /* createPersistentCookie */);
                    string continueUrl = Request.QueryString["ReturnUrl"];
                    if (String.IsNullOrEmpty(continueUrl))
                    {
                        continueUrl = "~/";
                    }
                    Response.Redirect(continueUrl);
                }
                else
                {
                    LoginUser.FailureText = "Login Failure!";
                }
            }
            catch (Exception lex)
            {
                LoginUser.FailureText = lex.Message;
            }
        }