Page 2 of 2 <12
Topic Options
#188487 - 2008-06-30 10:46 PM Re: Run command against multiple user profiles [Re: Zactek]
Kdyer Offline
KiX Supporter
*****

Registered: 2001-01-03
Posts: 6241
Loc: Tigard, OR
No.. No.. No..

The User-Defined function (UDF) should **ALWAYS** sit outside your main script..

The way you set it up is poor practice in the sense, what if you want to use it again?

Plus, the other thing is that if you grab a copy of UDF, the author provides examples of how to use the UDF in the "real world."

I have some time to look at this script this afternoon. Just remember, how do you eat an elephant? One bite at a time! So, let's break this down to bite sized pieces to accomplish your goal.

Thanks,

Kent


Edited by Kdyer (2008-06-30 10:48 PM)
_________________________
Utilize these resources:
UDFs (Full List)
KiXtart FAQ & How to's

Top
#188488 - 2008-06-30 10:53 PM Re: Run command against multiple user profiles [Re: Kdyer]
Kdyer Offline
KiX Supporter
*****

Registered: 2001-01-03
Posts: 6241
Loc: Tigard, OR
Disregard this.. Move on to the next post..

Edited by Kdyer (2008-06-30 11:48 PM)
_________________________
Utilize these resources:
UDFs (Full List)
KiXtart FAQ & How to's

Top
#188490 - 2008-06-30 11:41 PM Re: Run command against multiple user profiles [Re: Kdyer]
Kdyer Offline
KiX Supporter
*****

Registered: 2001-01-03
Posts: 6241
Loc: Tigard, OR
OK.. Zach..

Let's break this up.. Get your copy routine dialed in first... Then build the rest of the code. I think this what you want.
 Code:
 BREAK ON
 CLS
 $default = ReadValue ("HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles","DefaultProfile")
 $appd = ReadValue('HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 'AppData')
 $profilepath = $appd+"\Microsoft\Outlook\"
 ??$profilepath
 ;?'CHECK FOR VALID CHARACTERS FOR FILENAMES'
 ;??
 $yr=@year
 $mo=RIGHT(100+@monthno,2)
 ;?$MO
 $md=RIGHT(100+@mdayno,2)
 ;?$MD
 ;?JOIN(SPLIT(@TIME,":"),"")
 ; -- note: Removed the Time as your will not have the same time throughout the day
 ; -- Also, of note: the ":" colon is not a valid character in a file name as in the file structure, the colon is used for drive letters

 IF EXIST("%SYSTEMDRIVE%\ALFASCRIPT\*"+$yr+$mo+$md+".bak")
    RETURN ; RETURN maybe better than EXIT as RETURN takes you back to where left off
 ELSE
    DEBUG ON
    COPY $profilepath+"*.NK2" "%SYSTEMDRIVE%\ALFASCRIPT\*"+$yr+$mo+$md+".bak"
 ENDIF


Now, the copy is done, let's build the rest of the code:
 Code:
 BREAK ON
 CLS
 DIM $servername, $nk2, $profilepath, $searchstring, $sharepath, $programpath, $cmdstring, $runline, $cmdline
 ;
 ;Edit Variables
 ;
 $yr=@year
 $mo=RIGHT(100+@monthno,2)
 ;?$MO
 $md=RIGHT(100+@mdayno,2)
 ;?$MD
 ;?JOIN(SPLIT(@TIME,":"),"")
 ; -- note: Removed the Time as your will not have the same time throughout the day
 ; -- Also, of note: the ":" colon is not a valid character in a file name as in the file structure, the colon is used for drive letters

 $servername = ho00060lp57
 ;For example $ServerName = "Server1" or "Server1.yourdomain.com"
 $default = ReadValue ("HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles","DefaultProfile")
 $appd = ReadValue('HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 'AppData')
 $profilepath = $appd+"\Microsoft\Outlook\"
 $searchstring = "zactek@@msn.com"

 $sharepath = "\\" + $servername + "\nk2view\"
 $programpath = $sharepath + "nk2view.exe"

 ;This section fills in the default NK2 path
 IF NOT EXIST($profilepath)
    $profilepath = "%USERPROFILE%\Application Data\Microsoft\Outlook\Outlook.NK2"
 ENDIF

 IF EXIST("%SYSTEMDRIVE%\ALFASCRIPT\*"+$yr+$mo+$md+".bak")
       RETURN ; RETURN maybe better than EXIT as RETURN takes you back to where left off
 ELSE
    IF EXIST($appd+'\Microsoft\Outlook\*.nk2')
       COPY $profilepath+"*.NK2" "%SYSTEMDRIVE%\ALFASCRIPT\*"+$yr+$mo+$md+".bak"
       $rc=WshPipe('%comspec% /c dir /b "'+$profilepath+'*.NK2"',1)
       FOR EACH $line IN $rc
          IF NOT instr($line, "File Not Found")
             $cmdstring = $programpath + ' /nk2file "' + $profilepath+$line + '"'
             $runline = $cmdstring + ' /delete ' + $searchstring
             SHELL $runline
          ENDIF
       NEXT
     ENDIF
 ENDIF

 ?'Process is complete'
 GET $

 ;
 ;Function:
 ;   WshPipe()
 ;
 ;Author:
 ;   Christopher Shilt (christopher.shilt@relizon.com)
 ;
 ;Version:
 ;   1.3
 ;
 ;Version History:
 ;
 ;   13 Feb 2004  Version 1.3 - Removed Status Loop.
 ;
 ;   18 June 2003 Version 1.2 - Cleaned up code. Added error checking for support of the
 ;                              WScript.Shell.Exec method.
 ;
 ;   14 June 2002 Version 1.0 - Original Version.
 ;
 ;Action:
 ;   Runs an application in a child command-shell, providing access to the StdOut/StdErr
 ;   streams. Pipes the output to an array and returns the ExitCode of the command to the
 ;   @ERROR macro.
 ;
 ;Syntax:
 ;   WshPipe(COMMAND, optional NOECHO)
 ;
 ;Parameters:
 ;   COMMAND : REQUIRED. String value indicating the command line used to run the script.
 ;                       The command line should appear exactly as it would if you typed
 ;                       it at the command prompt.
 ;
 ;   NOECHO  : OPTIONAL. Suppress the command's output to the console, ouput is still
 ;                       stored in an array.
 ;
 ;Remarks:
 ;
 ;Returns:
 ;   Output of COMMAND in an array, ExitCode of the COMMAND in the @ERROR macro. By
 ;   default, the output is echoed to the screen but can be suppressed.
 ;
 ;Dependencies:
 ;   KiX 4.02
 ;   WSH 5.6 (Included with Microsoft Internet Explorer 6.0. Also available for download
 ;           from Microsoft's MSDN website.)
 ;
 ;Example:
 ;
 ; ; Display all KiX files in C:\ directory
 ; $rc=WshPipe("dir c:\*.kix")
 ; @ERROR " | " @SERROR ?
 ;
 ; ; Display all KiX files in C:\ directory, but suppress output to screen
 ; $rc=WshPipe("%comspec% /c dir c:\*.kix",1)
 ; @ERROR " | " @SERROR ?
 ;
 ; ; Display all KiX files in C:\ directory, suppress output to screen. Then use FOR/NEXT
 ; ; to exclude data.
 ; $rc=WshPipe("%comspec% /c dir c:\*.kix",1)
 ; for each $line in $rc
 ;    if not instr($line, "File Not Found")
 ;       ? $line
 ;    endif
 ; next
 ; @ERROR " | " @SERROR ?
 ;
 ;Source
 FUNCTION WshPipe($shellcmd, OPTIONAL $noecho)
       DIM $oexec, $output
       $oexec = CreateObject("WScript.Shell").exec($shellcmd)
       IF NOT VarType($oexec)=9 $wshpipe="WScript.Shell Exec Unsupported" 
             EXIT 10 
       ENDIF
       $output = $oexec.stdout.readall + $oexec.stderr.readall
       IF NOT $noecho $output 
       ENDIF
       $wshpipe=Split(Join(Split($output,CHR(13)),''),CHR(10))
       EXIT($oexec.exitcode)
 ENDFUNCTION


This should take care of your needs.

HTH,

Kent


Edited by Kdyer (2008-06-30 11:42 PM)
_________________________
Utilize these resources:
UDFs (Full List)
KiXtart FAQ & How to's

Top
#188497 - 2008-07-01 02:22 PM Re: Run command against multiple user profiles [Re: Kdyer]
Glenn Barnas Administrator Offline
KiX Supporter
*****

Registered: 2003-01-28
Posts: 4349
Loc: New Jersey
FYI - I have a tool on my web site that makes working with UDFs very easy...

"KGen" is a "UDF Resolver" tool. It's available in the KixDev package, and it works like this:

You create a folder where you develop your scripts - lets say D:\Dev. In this location, you create a folder called KixLib and place all of your UDFs in that folder. Create a Bin folder and place Kix32.exe and the two KGEN scripts there. Add D:\Dev\Bin to your PATH so it can find the scripts. Create a System environment variable called "KixLibPath" and define it as "D:\Dev\Kixlib".

Create additional folders for each of your script projects in D:\dev. Assume this project is called MPUpdate (Multi-Profile Update), so create D:\Dev\MPUpdate.

So - now you have D:\Dev\KixLib, D:\Bin, and D:\MPUpdate. Go to the MPUpdate folder and create "mpupdate.txt", and place all your code for this project in that file. Do not place any UDFs in the file, although you can reference any of your UDFs freely!

When you are ready to try your code, simply open a command prompt, CD to D:\Dev\MPUpdate and type "KGEN MPUPDATE" - it will read your mpupdate.txt file, determine all needed UDFs (based on what exists in your library) and create a .KIX file with your code and all required UDFs. It will also perform a sanity check, looking for mismatched quotes, parens, and similar issues. It also identifies issues with variables, such as duplicate definitions, defined bun unused, and undeclared.

That's all it takes, although that's barely scratched the surface of the KGen capabilities. You can break large projects into smaller, managable chunks (I've got a project with over 12,000 lines of code in 15 files), and create a BUILD.INI file that tells KGen what to do in the project folder (name of project, tokenize the .KIX file, run Sanity or not, strip comments, copy the script to other locations, etc). With the build.ini file, you just type "KGen" and it knows what to do.

BTW - KGen is a recursive resolving engine. That means if you have a UDF in your library that depends on another UDF, KGen will place that UDF in your script, too.

Glenn
_________________________
Actually I am a Rocket Scientist! \:D

Top
#188506 - 2008-07-01 11:43 PM Re: Run command against multiple user profiles [Re: Glenn Barnas]
Zactek Offline
Fresh Scripter

Registered: 2008-06-25
Posts: 12

Kent,

After a little modification to get the appending the way that I wanted, I was able to get this work successfully in our environment. It works for both Windows XP w/Outlook and Vista Users. Here is the scrubbed code:

 Code:
:nk2
Dim $servername, $default, $appd, $profilepath, $searchstring, $sharepath, $programpath, $cmdstring, $runline, $rc, $line
 ;*********Edit Variables*****************
 $iteration = A1
 $yr=@year
 $mo=Right(100+@monthno,2)
 $md=Right(100+@mdayno,2)
 $servername = server1
 $profilepath = %appdata%\Microsoft\Outlook\
 $searchstring = "username@@domain.com"
 $sharepath = "\\" + $servername + "\nk2view\"
 $programpath = $sharepath + "nk2view.exe"
 ;***************************************
 If Not Exist($profilepath)
    $profilepath = "%USERPROFILE%\Application Data\Microsoft\Outlook\Outlook.NK2"
 EndIf
 If Exist("%SYSTEMDRIVE%\SHARENAME\*.bak*")
       Return
     Else
   If Exist($profilepath+'*.nk2')
       Copy $profilepath+"*.NK2" "%SYSTEMDRIVE%\SHARENAME\*.bak"+"_"+$iteration+"_"+$yr+$mo+$md
       $rc=WshPipe('%comspec% /c dir /b "'+$profilepath+'*.NK2"',1)
       For Each $line in $rc
          If Not InStr($line, "File Not Found")
             $cmdstring = $programpath + ' /nk2file "' + $profilepath+$line + '"'
             $runline = $cmdstring + ' /delete ' + $searchstring
             Shell $runline
          EndIf
       Next
     EndIf
 EndIf

;************************************************************************************
  Function WshPipe($shellcmd, OPTIONAL $noecho)
       Dim $oexec, $output
       $oexec = CreateObject("WScript.Shell").exec($shellcmd)
       If Not VarType($oexec)=9 $wshpipe="WScript.Shell Exec Unsupported" 
             Exit 10 
       EndIf
       $output = $oexec.stdout.readall + $oexec.stderr.readall
       If Not $noecho $output 
       EndIf
       $wshpipe=Split(Join(Split($output,Chr(13)),''),Chr(10))
       Exit($oexec.exitcode)
 EndFunction
Return 


We had challenges with the following value because this value wasn't what the default location is supposed to be for Vista - Outlook users.
 Code:
$appd = ReadValue('HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 'AppData')


For one user, we would verify via the Registry Editor and it was a different value than what you would get at the command line using "set" or Start | Run %appdata%. It was kind of weird, so we decided to use %appdata%\Microsoft\Outlook\

Top
#188507 - 2008-07-01 11:55 PM Re: Run command against multiple user profiles [Re: Zactek]
Kdyer Offline
KiX Supporter
*****

Registered: 2001-01-03
Posts: 6241
Loc: Tigard, OR
2 things..

(1) I would remove the last line: return..

(2) If you are going to use a UDF, I would include the "Header" Information.. What would happen if you left the company? Plus, you should give credit where credit is due: Neither you nor me wrote this UDF.

I would recommend reading the following topic.
Best Practices and Methods

Also, there are a number of great topics at: KiXtart FAQ & How to's

Thanks,

Kent
_________________________
Utilize these resources:
UDFs (Full List)
KiXtart FAQ & How to's

Top
Page 2 of 2 <12


Moderator:  Glenn Barnas, NTDOC, Arend_, Jochen, Radimus, Allen, ShaneEP, Ruud van Velsen, Mart 
Hop to:
Shout Box

Who's Online
0 registered and 131 anonymous users online.
Newest Members
dimi575, Drecksnacken, Nlill, webtools321, multiman
17734 Registered Users

Generated in 0.033 seconds in which 0.011 seconds were spent on a total of 14 queries. Zlib compression enabled.

Search the board with:
superb Board Search
or try with google:
Google
Web kixtart.org