Zactek
(Fresh Scripter)
2008-06-25 04:44 PM
Run command against multiple user profiles

Essentially, I am trying to run a command through a KIX login script that will run a utility that can delete a specific entry from the NK2 file. This utility is called NK2View. You can use switches from the command line to perform a delete of a record within the NK2 file upon login.

 Code:
nk2view.exe /delete username@domain.com 


I have researched on this and other forums different ways to try and do this, but I have only found code to delete the entire file itself. This example is from a post from NTDOC -
 Code:
$nk2=ReadValue('HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 'AppData')
If Exist($nk2+'\Microsoft\Outlook\*.nk2')=1  
;Searches for files ending with .NK2 and deletes them.  
Del($nk2+'\Microsoft\Outlook\*.nk2')EndIf 


Another one of the challenges is also trying to get this to apply to users that are have Windows XP and Vista because the paths are different. I need to get this to run upon logon, so I probably don't need to feed in a list of computer names, but I do need to run this utility remotely against multiple user's computers and multiple profiles. Also, I may have 2 paths because some are still on XP with different versions of Outlook -

 Code:
 [b]Outlook 2000 / 2003 / 2007[/b] - \\%computername%\C$\Documents and Settings\%userprofile%\Application Data\Microsoft\Outlook\outlook.nk2

[b]Microsoft Vista with Outlook[/b] - \\%computername%\C$\Users\%userprofile%\AppData\Roaming\Microsoft\Outlook\outlook.nk2


Anyhow, any help is appreciated.


Kdyer
(KiX Supporter)
2008-06-25 04:50 PM
Re: Run command against multiple user profiles

Zactek,

You should be able to use %APPDATA% as the variable. Just went to a command prompt and typed in SET to see what Environment Variables are available.

Also, you could do this from the Registry:
 Code:
$AppData = READVALUE('HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders','AppData')

This is also included in Doc's code. Probably the easiest way to do this is at login. Sure, you could do this remotely, but will be more difficult.

HTH,

Kent


Zactek
(Fresh Scripter)
2008-06-25 05:02 PM
Re: Run command against multiple user profiles

Kent,

What about if I want to backup / change the existing to a backup (e.g. *.bak) and then execute this utility? I'm trying to get a fuller example of how I could do this. Any help is appreciated!

Thank You,
Zactek


Zactek
(Fresh Scripter)
2008-06-26 04:50 PM
Re: Run command against multiple user profiles

This is essentially what I am trying to do within the KiXtart script, but at the command line it is returning a value of zero (0) :

 Code:
Dim $ServerName, $nk2, $ProfilePath, $SearchString, $SharePath, $ProgramPath, $CmdString, $RunLine, $CmdLine	
;
;Edit Variables
;
$ServerName = 
;For example $ServerName = "Server1" or "Server1.yourdomain.com"
$nk2 = ReadValue('HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 'AppData')
$ProfilePath = $nk2+"\Microsoft\Outlook\"
;For example $ProfilePath = "%USERPROFILE%\Application Data\Microsoft\Outlook\Outlook.NK2", or "Null"
$SearchString = 
;
;-------------------------------------------------------------------------------------------------------------------------------------------
;-------------------------------------------------------------------------------------------------------------------------------------------
$SharePath = "\\" + $ServerName + "\nk2view\"
$ProgramPath = $SharePath + "nk2view.exe"

;This section fills in the default NK2 path
If $ProfilePath = "Null"
	$ProfilePath = "%USERPROFILE%\Application Data\Microsoft\Outlook\Outlook.NK2"
EndIf

If Exist($nk2+'\Microsoft\Outlook\*.bak*')=1
;Searches for files ending with .BAK and that may have anything appended and then stops script if condition is true
	Goto EOF
EndIf

If Exist($nk2+'\Microsoft\Outlook\*.nk2')=1  
;Searches for files ending with .NK2 and creates backup.  
	Move($nk2+'\Microsoft\Outlook\*.nk2') ($nk2+'\Microsoft\Outlook\*.bak+@YEAR+@MONTHNO+@MDAYNO+@TIME')
EndIf

$CmdString = $ProgramPath + "/nk2file " + $ProfilePath

:SearchDelete
$Runline = $CmdString + " /delete " + $SearchString
GoTo CmdLine

:CmdLine
 Shell $Runline

:EOF
Exit
Exit


Kdyer
(KiX Supporter)
2008-06-26 06:45 PM
Re: Run command against multiple user profiles

One thing that pops in to my mind is trying to read in the local user's information if you are to run this Remotely. It is pretty easy to do a READVALUE remotely on HKLM, but HKCU is more painful from an Admin side as you have to know the SID..

I did clean up your code a bit too.
 Code:
 DIM $servername, $nk2, $profilepath, $searchstring, $sharepath, $programpath, $cmdstring, $runline, $cmdline
 ;
 ;Edit Variables
 ;
 $servername = @lserver
 ;For example $ServerName = "Server1" or "Server1.yourdomain.com"
 $nk2 = ReadValue('HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 'AppData')
 $profilepath = $nk2+"\Microsoft\Outlook\"
 ;For example $ProfilePath = "%USERPROFILE%\Application Data\Microsoft\Outlook\Outlook.NK2", or "Null"
 $searchstring =
 ;-------------------------------------------------------------------------------------------------------------------------------------------
 ;-------------------------------------------------------------------------------------------------------------------------------------------
 $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($nk2+'\Microsoft\Outlook\*.bak'+@YEAR+@MONTHNO+@MDAYNO+@TIME)
       RETURN ; RETURN maybe better than EXIT as RETURN takes you back to where left off
 ENDIF

 IF EXIST($nk2+'\Microsoft\Outlook\*.nk2')
       ;Searches for files ending with .NK2 and creates backup.
       MOVE $nk2+'\Microsoft\Outlook\*.nk2' $nk2+'\Microsoft\Outlook\*.bak'+@YEAR+@MONTHNO+@MDAYNO+@TIME
       $cmdstring = $programpath + "/nk2file " + $profilepath
       $runline = $cmdstring + " /delete " + $searchstring
       SHELL $runline
 ENDIF


HTH,

Kent


Zactek
(Fresh Scripter)
2008-06-26 09:16 PM
Re: Run command against multiple user profiles

Kent,

Does the @lserver macro include the double backslashes in its output? Also, if I wanted to run this for multiple iterations, I may want to name the *.BAK files with a unique variable and possibly delete older variables. Do you have any other suggestions for something like this? Thanks for all of your help!

Thank You,
Zach Crawford


Zactek
(Fresh Scripter)
2008-06-26 09:32 PM
Re: Run command against multiple user profiles

\:\( - I'm still not able to getting this to work. The KiX debug hasn't been that helpful. Here is the tool that I am trying to use - NK2View

Here is the exact code that I am trying to run:

 Code:
DIM $servername, $nk2, $profilepath, $searchstring, $sharepath, $programpath, $cmdstring, $runline, $cmdline
 ;
 ;Edit Variables
 ;
 $servername = ho00060lp57
 ;For example $ServerName = "Server1" or "Server1.yourdomain.com"
 $nk2 = ReadValue('HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 'AppData')
 $profilepath = $nk2+"\Microsoft\Outlook\"
 ;For example $ProfilePath = "%USERPROFILE%\Application Data\Microsoft\Outlook\Outlook.NK2", or "Null"
 $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($nk2+'\Microsoft\Outlook\*.bak'+@YEAR+@MONTHNO+@MDAYNO+@TIME)
       RETURN ; RETURN maybe better than EXIT as RETURN takes you back to where left off
 ENDIF

 IF EXIST($nk2+'\Microsoft\Outlook\*.nk2')
       ;Searches for files ending with .NK2 and creates backup.
       MOVE $nk2+'\Microsoft\Outlook\*.nk2' $nk2+'\Microsoft\Outlook\*.bak'+@YEAR+@MONTHNO+@MDAYNO+@TIME
       $cmdstring = $programpath + "/nk2file " + $profilepath
       $runline = $cmdstring + " /delete " + $searchstring
       SHELL $runline
 ENDIF


The only thing that I changed was using my local computer name and my personal e-mail address in the $searchString. There is a share on my computer that I have rights to with the name of "nk2view".


Kdyer
(KiX Supporter)
2008-06-26 10:24 PM
Re: Run command against multiple user profiles

OK.. I think we need to revisit a couple of things here..

You are doing a MOVE, which means that you are taking a file and moving it to another name. So, how can nk2view act on the file when it is renamed or moved to another name?

Debugging is a cinch in KiX.. You can initiate a debug on in your script.. You can then look at the resulting @error and @serror macros to see what is going on.

Also, you can do kix32 /d yourscript.kix

This stuff is discussed in the FAQ Forum..

So.. Here is what I have put together so far (still not working, but closer):

 Code:
BREAK ON
CLS
DIM $servername, $nk2, $profilepath, $searchstring, $sharepath, $programpath, $cmdstring, $runline, $cmdline
 ;
 ;Edit Variables
 ;
 $servername = ho00060lp57
 ;For example $ServerName = "Server1" or "Server1.yourdomain.com"
 $AppD = ReadValue('HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 'AppData')
 ???$AppD
 $profilepath = $AppD+"\Microsoft\Outlook\"
 ;For example $ProfilePath = "%USERPROFILE%\Application Data\Microsoft\Outlook\Outlook.NK2", or "Null"
 $searchstring = "test@test.com"
 ;-------------------------------------------------------------------------------------------------------------------------------------------
 ;-------------------------------------------------------------------------------------------------------------------------------------------
 $sharepath = @scriptdir + "\"
 ;$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($AppD+'\Microsoft\Outlook\*.bak'+@YEAR+@MONTHNO+@MDAYNO+@TIME)
       RETURN ; RETURN maybe better than EXIT as RETURN takes you back to where left off
 ENDIF

 IF EXIST($AppD+'\Microsoft\Outlook\*.nk2')
       ;Searches for files ending with .NK2 and creates backup.
       ; -- You want to do a copy to backup before messing with the file...
       debug on
       ???'"'+$profilepath+'*.NK2'+'"'
       CD $profilepath
       COPY '"'+'*.NK2'+'"' '"'+'*.bak'+'"'
       ;COPY "MyDir\file*.txt" "MyDir\file*.bak"

       ???@SERROR+@ERROR
       ;MOVE $AppD+'\Microsoft\Outlook\*.nk2' $AppD+'\Microsoft\Outlook\*.bak'+@YEAR+@MONTHNO+@MDAYNO+@TIME
       $cmdstring = $programpath + "/nk2file " + $profilepath
       $runline = $cmdstring + " /delete " + $searchstring
       SHELL $runline
 ENDIF

get $


HTH,

Kent


Kdyer
(KiX Supporter)
2008-06-26 10:55 PM
Re: Run command against multiple user profiles

OK.. Spent some time on this for you.. It now works..

 Code:
BREAK ON
CLS
DIM $servername, $nk2, $profilepath, $searchstring, $sharepath, $programpath, $cmdstring, $runline, $cmdline
 ;
 ;Edit Variables
 ;
 $servername = ho00060lp57
 ;For example $ServerName = "Server1" or "Server1.yourdomain.com"
 $AppD = ReadValue('HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 'AppData')
 ???$AppD
 $profilepath = $AppD+"\Microsoft\Outlook\"
 ;For example $ProfilePath = "%USERPROFILE%\Application Data\Microsoft\Outlook\Outlook.NK2", or "Null"
; NOTE: Don't forget to double up the @@ for an e-mail address
 $searchstring = "test@@test.com"
 ;-------------------------------------------------------------------------------------------------------------------------------------------
 ;-------------------------------------------------------------------------------------------------------------------------------------------
 $sharepath = "c:\!KIX\"
 ;$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($AppD+'\Microsoft\Outlook\*.bak'+@YEAR+@MONTHNO+@MDAYNO+@TIME)
       RETURN ; RETURN maybe better than EXIT as RETURN takes you back to where left off
 ENDIF

 IF EXIST($AppD+'\Microsoft\Outlook\*.nk2')
       ;Searches for files ending with .NK2 and creates backup.
       ; -- You want to do a copy to backup before messing with the file...
       ; -- You may also do a check to insure Outlook is closed before proceeding
       debug on
       SHELL '%COMSPEC% /C COPY "'+$profilepath+'*.NK2" "'+$profilepath+'*.bak"'
       ;COPY "MyDir\file*.txt" "MyDir\file*.bak"

       ???@SERROR+@ERROR
       ;MOVE $AppD+'\Microsoft\Outlook\*.nk2' $AppD+'\Microsoft\Outlook\*.bak'+@YEAR+@MONTHNO+@MDAYNO+@TIME
       ; NOTE: You may run into a problem with multiple nk2 files...  '*.NK2"'
       $cmdstring = $programpath + ' /nk2file "' + $profilepath+'*.NK2"'
       ?$cmdstring
       $runline = $cmdstring + ' /delete ' + $searchstring
       ?$RUNLINE
       SHELL $runline
       ???@SERROR+@ERROR
 ENDIF

get $


HTH,

Kent


Zactek
(Fresh Scripter)
2008-06-26 11:18 PM
Re: Run command against multiple user profiles

Kent,

Thanks for all of your work on this. I'm not sure if there was a question on the $AppD but it's supposed to read in that system setting for %AppData%. I'm hoping that I clearly explained what I'm trying to accomplish with this script.

Thank You,
Zach Crawford


Zactek
(Fresh Scripter)
2008-06-26 11:47 PM
Re: Run command against multiple user profiles


Kent,
It looked like that it copied the file and made the *.bak, but the application that I am using didn't delete the entry from the NK2 file even when I used "zactek@@msn.com" in the $searchString variable. Also, is there a way to append a unique value to the end of the backup file? I was initially thinking like date/time and then try to delete any backup files that were before that iterations date/time if we ran this multiple times. It's time for the MountainDew for me...

Thanks for all your help!
Zach


Kdyer
(KiX Supporter)
2008-06-27 04:16 PM
Re: Run command against multiple user profiles

Hang tight.. I am going to look at something a bit different for you.

Kent


Kdyer
(KiX Supporter)
2008-06-27 04:41 PM
Re: Run command against multiple user profiles

OK.. Got it.. Need to use the following UDF: WSHPIPE.

Here is the code..

 Code:
BREAK ON
CLS
DIM $servername, $nk2, $profilepath, $searchstring, $sharepath, $programpath, $cmdstring, $runline, $cmdline
 ;
 ;Edit Variables
 ;
 $servername = ho00060lp57
 ;For example $ServerName = "Server1" or "Server1.yourdomain.com"
 $AppD = ReadValue('HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders', 'AppData')
 ???$AppD
 $profilepath = $AppD+"\Microsoft\Outlook\"
 ;For example $ProfilePath = "%USERPROFILE%\Application Data\Microsoft\Outlook\Outlook.NK2", or "Null"
 $searchstring = "you@@domain.com"
 ;-------------------------------------------------------------------------------------------------------------------------------------------
 ;-------------------------------------------------------------------------------------------------------------------------------------------
 $sharepath = "c:\!KIX\"
 ;$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($AppD+'\Microsoft\Outlook\*.bak'+@YEAR+@MONTHNO+@MDAYNO+@TIME)
       RETURN ; RETURN maybe better than EXIT as RETURN takes you back to where left off
 ENDIF

 IF EXIST($AppD+'\Microsoft\Outlook\*.nk2')
       ;Searches for files ending with .NK2 and creates backup.
       ; -- You want to do a copy to backup before messing with the file...
       ;;debug on
       ??$profilepath
       ;;SHELL '%COMSPEC% /C COPY "'+$profilepath+'*.NK2" "'+$profilepath+'*.bak"'
       ;COPY "MyDir\file*.txt" "MyDir\file*.bak"

       ; -- LOOK FOR NK2 FILES

       ???@SERROR+@ERROR
       ;MOVE $AppD+'\Microsoft\Outlook\*.nk2' $AppD+'\Microsoft\Outlook\*.bak'+@YEAR+@MONTHNO+@MDAYNO+@TIME
       ; NOTE: You may run into a problem with multiple nk2 files...  '*.NK2"'

       $rc=WshPipe('%comspec% /c dir /b "'+$profilepath+'*.NK2"',1) 
       for each $line in $rc 
           if not instr($line, "File Not Found") 
              ? $line 
              ;>>
              $cmdstring = $programpath + ' /nk2file "' + $profilepath+$line + '"'
              $runline = $cmdstring + ' /delete ' + $searchstring
              SHELL $runline
              ???@SERROR+@ERROR
           ;>>
           endif 
       next 
       @ERROR " | " @SERROR ? 
 ENDIF
?'Process is complete'
get $



HTH,

Kent


Zactek
(Fresh Scripter)
2008-06-27 07:26 PM
Re: Run command against multiple user profiles


Kent,

When I tried to execute from the command line, but I got -

The operation completed successfully.0
ERROR : expected ')'!
Script: C:\NK2View\nk2view_new.kix
Line : 43

The only change that I made was to use my computer and path. This appears to be the line for the start of your WshPipe UDF.

Thank You,
Zach Crawford


Kdyer
(KiX Supporter)
2008-06-27 07:29 PM
Re: Run command against multiple user profiles

Zach,

Note the link for the WSHPIPE UDF above. You will need to go copy/paste that into the script as it is a separate "User Defined Function".

BTW, it is not my script. \:D

HTH,

Kent


Zactek
(Fresh Scripter)
2008-06-27 08:31 PM
Re: Run command against multiple user profiles

Kent,

I did see that Chris had his initial posting, but then it looks like a later update to the code was on his #83231 - 04/02/13 07:52 PM Posting. Is this is the one that I should be using within the code?

Thanks!
Zach


Zactek
(Fresh Scripter)
2008-06-27 08:45 PM
Re: Run command against multiple user profiles

\:\)
Kent,

I added the UDF code from that post I mentioned and the executable ran successfully and deleted the NK2 file entry. Now I need some help on the copy, move, rename of the file. Basically the intent of the script is to check to see if there are any *.bak files in the %APPDATA%\Microsoft\Outlook\ folder and if not, create a copy of the file and rename it to *.bak with appended information and then run an application that is used to remove an entry from the original NK2 file. I am also looking for a way to get all NK2 files, back them up and then run this utility against the original. I am not sure if something like this would help get around some of the technical challenges of getting "everything".

 Code:
$PrfName = ReadValue ("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles","DefaultProfile")
$nk2 = "%APPDATA%\Microsoft\Outlook\" + $prfname + ".nk2"


I appreciate yours and anyone else's help on this!
Thank You,
Zach Crawford


Kdyer
(KiX Supporter)
2008-06-27 09:53 PM
Re: Run command against multiple user profiles

 Originally Posted By: Zactek
Kent,

I did see that Chris had his initial posting, but then it looks like a later update to the code was on his #83231 - 04/02/13 07:52 PM Posting. Is this is the one that I should be using within the code?

Thanks!
Zach


Zach - Any UDF that is posted: You should used the UDF from the initial post and that is it. If there are modifications to a UDF, people usually PM the Author and as needed, changes made to the initial post of the UDF.

HTH,

Kent


Kdyer
(KiX Supporter)
2008-06-27 10:30 PM
Re: Run command against multiple user profiles

Zach,

(1) The WSHPIPE UDF gives you a facility to look for each file that exists in a user profile, back up the file, act on it and then go to the next.

(2) I would become familiar with the UDF Libarary (it is your KiXtart friend!)..
UDF Libary

The UDF Libary in the discussion forum is a bit cumbersome for navigation to put together a list of UDFs and if you read the first post from NTDOC, he explains about the parsed out list of UDFs with an included search tool as well.
UDF Library Collection Sites - Sorted List of UDF

http://www.kixtart.org/UDF is the whole collection of UDFs.

Hmm.. Check this out.. This may help in enumerating profiles remotely.
Profile list


Thanks,

Kent


Zactek
(Fresh Scripter)
2008-06-30 03:45 PM
Re: Run command against multiple user profiles

Kent,

I appreciate you pointing out some more of the resources on KiXtart website. I am just unsure about the first statement in your post because I don't know exactly how to use it to copy / backup each NK2 file within that function. This is the code that I have where it does run the application I'm using, but it doesn't copy / backup the NK2 file. When I do the backup, I need to find a way to append a unique value to the end of the file extension (e.g. Outlook.NK2_A1). I want to copy this file to another location (e.g. %SYSTEMDRIVE%\alfascript\ ) Any more help is appreciated!

 Code:
BREAK ON
CLS
DIM $servername, $nk2, $profilepath, $searchstring, $sharepath, $programpath, $cmdstring, $runline, $cmdline
 ;
 ;Edit Variables
 ;
 $servername = ho00060lp57
 ;For example $ServerName = "Server1" or "Server1.yourdomain.com"
 $AppD = ReadValue ("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles","DefaultProfile")
 $profilepath = $AppD+"\Microsoft\Outlook\"
 ;For example $ProfilePath = "%USERPROFILE%\Application Data\Microsoft\Outlook\Outlook.NK2", or "Null"
 $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($AppD+'\Microsoft\Outlook\*.bak'+@YEAR+@MONTHNO+@MDAYNO+@TIME)
       RETURN ; RETURN maybe better than EXIT as RETURN takes you back to where left off
 ENDIF

 IF EXIST($AppD+'\Microsoft\Outlook\*.nk2')
       ;Searches for files ending with .NK2 and creates backup.
       ; -- You want to do a copy to backup before messing with the file...
       ;;debug on
       ??$profilepath
       ;;SHELL '%COMSPEC% /C COPY "'+$profilepath+'*.NK2" "'+$profilepath+'*.bak"'
       ;COPY "MyDir\file*.txt" "MyDir\file*.bak"

       ; -- LOOK FOR NK2 FILES

       ???@SERROR+@ERROR
       COPY $AppD+'\Microsoft\Outlook\*.nk2' $AppD+'\Microsoft\Outlook\*.bak'
       ; NOTE: You may run into a problem with multiple nk2 files...  '*.NK2"'
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
	 $rc=WshPipe('%comspec% /c dir /b "'+$profilepath+'*.NK2"',1) 
       for each $line in $rc 
           if not instr($line, "File Not Found") 
              ? $line 
              ;>>
              $cmdstring = $programpath + ' /nk2file "' + $profilepath+$line + '"'
              $runline = $cmdstring + ' /delete ' + $searchstring
              SHELL $runline
              ???@SERROR+@ERROR
           ;>>
           endif 
       next 
       @ERROR " | " @SERROR ? 
 ENDIF
?'Process is complete'
get $


Kdyer
(KiX Supporter)
2008-06-30 10:46 PM
Re: Run command against multiple user profiles

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


Kdyer
(KiX Supporter)
2008-06-30 10:53 PM
Re: Run command against multiple user profiles

Disregard this.. Move on to the next post..

Kdyer
(KiX Supporter)
2008-06-30 11:41 PM
Re: Run command against multiple user profiles

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


Glenn BarnasAdministrator
(KiX Supporter)
2008-07-01 02:22 PM
Re: Run command against multiple user profiles

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


Zactek
(Fresh Scripter)
2008-07-01 11:43 PM
Re: Run command against multiple user profiles


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\


Kdyer
(KiX Supporter)
2008-07-01 11:55 PM
Re: Run command against multiple user profiles

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