**DONOTDELETE**
(Lurker)
2001-05-21 07:24 AM
Long post - Special characters within quotes or in variables

NOTE: Scripts are listed at the end (they are lengthy).

I am having difficulties embedding special characters in variables. I have found that in the beta, the embedding of % no longer works. It used to be that by doubling up the %, @ and $ symbols, those symbols could be used in an embedded fashion (within quotes or variables). I have included my work so that if I am in error, the error can be seen:-)

I discovered this change while attempting to change passwords on a series of servers (several hundred) that we administer within our administration group. To that end, I have been testing password.exe and KIX scripting with lists in text files.

Our group is using a random password generator to create a list of passwords. My means of accomplishing the changes is via reading lists, a list containing the user names, a list containing the server/domain names, a list of the old passwords, and a list with the new passwords. Then the script changes the passwords in one fell swoop (with output to document results).

However, in testing, I have found several characters that are problematic (when embedded in a variable). I decided to test embedding each character that could be used in a variable. To do this, I wrote another script to test embedding.

My test script, variable list and password script are all at the end of the post.

The issue with the embedded characters in strings (variables) lies in that I can embed characters 33-255 with the exceptions being
34 ("), 38 (&), 39 ('), 60 (< ), 62 (> ), and 124 (|). Characters 1-32 are unimportant as they appear to be Control characters. Most of the characters after 126 are unimportant too (being non-standard keyboard characters).

If anyone has the patience to look through these, perhaps you might comment on better ways to perform these functions and perhaps workarounds or solutions to how to embed these 6 characters. I am still new to scripting and while aware that there are shorter ways to script some of these, have not yet aquired the technical knowledge to write these shortcuts. If you know how to shorten the scripts that feedback would be appreciated as well.

VARIABLETEST.KIX

$var1=""
$var2=4
$count=""
close(1)
REDIRECTOUTPUT ("d:\test\result.txt",0)
IF OPEN (1, "D:\test\vartest.txt",0) =0
$var1=READLINE(1)
$count=33
? "This is what embedded variable $count looks like: ($var1)"
? "These variables will now be tested in a password change."
WHILE @ERROR=0
shell '%comspec% /c password.exe -p new' + $var2 + ' new' + $var1 + ' -u user01 -d \\server01'
select
case @error = 0
? "The password was changed"
case @error = 86
? "Wrong current password"
case @error = 2245
? "Invalid new password"
case @error = 1327
? "You are unable to change this password at this time"
case @error = 5
? "You do not have permission to change your Password"
case 1
? 'An unknown Error "#@error:@serror" has occured'
endselect
sleep 2
$var2=$var1
$var1=READLINE(1)
$count=1+$count
? "This is what embedded variable $count looks like: ($var1)"
DIR ("D:\XFILE\NEWGEN")
IF $COUNT > 255
GOTO FINISH
ELSE
ENDIF
LOOP

:FINISH
ENDIF
CLOSE (1)
$var1=""
$var2=""
$count=""
EXIT

The text file which it reads is as follows:

VARTEST.TXT

'!'
'2quote'
'#'
'$$'
'%%'
'ampersand'
'quote'
'('
')'
'*'
'+'
','
'-'
'.'
'/'
'0'
'1'
'2'
'3'
'4'
'5'
'6'
'7'
'8'
'9'
':'
';'
'less'
'='
'greater'
'?'
'@@'
'A'
'B'
'C'
'D'
'E'
'F'
'G'
'H'
'I'
'J'
'K'
'L'
'M'
'N'
'O'
'P'
'Q'
'R'
'S'
'T'
'U'
'V'
'W'
'X'
'Y'
'Z'
'['
'\'
']'
'^'
'_'
'`'
'a'
'b'
'c'
'd'
'e'
'f'
'g'
'h'
'i'
'j'
'k'
'l'
'm'
'n'
'o'
'p'
'q'
'r'
's'
't'
'u'
'v'
'w'
'x'
'y'
'z'
'{'
'pipe'
'}'
'~'
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''
''

Finally, the password change script is as follows:

CHANGEANYPASS.KIX

;Written by Sprint PCS Team
;Modified by Alex Baker
;5/18/2001
;Testing with Kixtart 4.00
;*******************************
;*** Instructions ***
;*******************************
;Run a random password generator
;to create a text list of
;passwords. Compile the list of
;known passwords for accounts
;for which to change passwords.
;Compile a list of servers or
;domains in which to change the
;passwords. Compile a list of
;user IDs that need changing.
;Place all four text lists in
;the Acctid folder.
;*******************************


;*******************************
;*** Change Userid Passwords ***
;*******************************
:Start
CLS


; *** Set some Variables ***
$ARCH="Archives"
$NTLIST="Acctid"
$YR="@STARTDIR\$ARCH\@YEAR"
$MTH="$YR\@Month"
$DAY="$MTH\@MdayNo"
$TIME=@Time
$TIME2=SUBSTR($TIME,1,2)+SUBSTR($TIME,4,2)+SUBSTR($TIME,7,2)
$LOG="$DAY\$TIME2"
$NTFILE="ACCTID.TXT"
$DOMSERVFILE="DOMSERV.TXT"
$CPASSFILE="CPASS.TXT"
$NPASSFILE="NPASS.TXT"
$UID=""
$DMSRV=""
$CPWD=""
$NPWD=""

IF EXIST ("@STARTDIR\$NTLIST\$NTFILE")
Else
CLS
BEEP BEEP BEEP
MESSAGEBOX ("$NTFILE was NOT found in $NTLIST Directory","NT Account File",16,0)
EXIT
ENDIF

IF EXIST ("@STARTDIR\$NTLIST\$DOMSERVFILE")
Else
CLS
BEEP BEEP BEEP
MESSAGEBOX ("$DOMSERVFILE was NOT found in $NTLIST Directory","Domain List File",18,0)
EXIT
ENDIF

IF EXIST ("@STARTDIR\$NTLIST\$CPASSFILE")
Else
CLS
BEEP BEEP BEEP
MESSAGEBOX ("$CPASSFILE was NOT found in $NTLIST Directory","NT Account File",20,0)
EXIT
ENDIF

IF EXIST ("@STARTDIR\$NTLIST\$NPASSFILE")
Else
CLS
BEEP BEEP BEEP
MESSAGEBOX ("$NPASSFILE was NOT found in $NTLIST Directory","NT Account File",22,0)
EXIT
ENDIF

Sleep 2

CLS

AT (15,5) "Have you entered the current passwords,"
AT (16,5) "userids, servers/domains, and new passwords? (Y/N)? "
GETS $1R
IF $1R="Y" GOTO GOOD
ELSE EXIT
ENDIF

:GOOD
CLS

; *** Create the Proper Audit Directories ***
MD "$YR"
MD "$MTH"
MD "$DAY"
MD "$LOG"

; *** Move Account list to Audit Directory ***
Copy "@STARTDIR\$NTLIST\$NTFILE" "$LOG\$NTFILE"
Copy "@STARTDIR\$NTLIST\$DOMSERVFILE" "$LOG\$DOMSERVFILE"
Copy "@STARTDIR\$NTLIST\$CPASSFILE" "$LOG\$CPASSFILE"
Copy "@STARTDIR\$NTLIST\$NPASSFILE" "$LOG\$NPASSFILE"
DEL "@STARTDIR\$NTLIST\$NTFILE"
DEL "@STARTDIR\$NTLIST\$DOMSERVFILE"
DEL "@STARTDIR\$NTLIST\$CPASSFILE"
DEL "@STARTDIR\$NTLIST\$NPASSFILE"

Shell '%Comspec% /c echo $LOG\RESULTS.TXT>"$LOG\RESULTS.TXT'

REDIRECTOUTPUT ("$LOG\RESULTS.TXT",0)

IF OPEN (1,"$LOG\$NTFILE",0) = 0
IF OPEN (2,"$LOG\$DOMSERVFILE",0) = 0
IF OPEN (3,"$LOG\$CPASSFILE",0) = 0
IF OPEN (4,"$LOG\$NPASSFILE",0) = 0
$UID=READLINE(1)
GLOBAL $UID
$DMSRV=READLINE(2)
GLOBAL $DMSRV
$CPWD=READLINE(3)
GLOBAL $CPWD
$NPWD=READLINE(4)
GLOBAL $NPWD
WHILE @ERROR = 0
? "NT Account ID: "+$UID

? "Domain or Server: "+$DMSRV
CALL CAP2.KIX
?
SLEEP 6
$UID=READLINE(1)
GLOBAL $UID
$DMSRV=READLINE(2)
GLOBAL $DMSRV
$CPWD=READLINE(3)
GLOBAL $CPWD
$NPWD=READLINE(4)
GLOBAL $NPWD
LOOP
ENDIF
ENDIF
ENDIF
ENDIF
CLOSE (1)
CLOSE (2)
CLOSE (3)
CLOSE (4)

CLS
MESSAGEBOX ("Completed!!!","Modified passwords",16,0)

; *** Clear variables ***
$ARCH=""
$NTLIST=""
$YR=""
$MTH=""
$DAY=""
$TIME=""
$TIME2=""
$LOG=""
$NTFILE=""
$DOMSERVFILE=""
$CPASSFILE=""
$NPASSFILE=""
$1R=""
$UID=""
GLOBAL $UID
$DMSRV=""
GLOBAL $DMSRV
$CPWD=""
GLOBAL $CPWD
$NPWD=""
GLOBAL $NPWD
SLEEP 2
EXIT

The called CAP2.KIX:

REDIRECTOUTPUT ("$LOG\RESULTS.TXT",0)
shell '%comspec% /c password -p $CPWD $NPWD -u $UID -d $DMSRV > nul'
select
case @error = 0
? "The password was changed"
case @error = 86
? "Wrong current password"
case @error = 2245
? "Invalid new password"
case @error = 1327
? "You are unable to change this password at this time"
case @error = 5
? "You do not have permission to change your Password"
case 1
? 'An unknown Error "#@error:@serror" has occured'
endselect
RETURN
EXIT


If you have read this far, wow! I appreciate your diligence. I hope this information helps you to see what I see.

Thanks,

Alex
abaker09@sprintspectrum.com


cj
(MM club member)
2001-05-22 08:54 AM
Re: Long post - Special characters within quotes or in variables

Long reply...

Hi and welcome to the board.

I played around with your script a little and this is the top of the result.txt I made:

code:

33 = ('!')
34 = ('"')
35 = ('#')
36 = ('$')
37 = ('%')
38 = ('&')
39 = (''')
40 = ('(')
41 = (')')
42 = ('*')
43 = ('+')
44 = (',')
45 = ('-')
46 = ('.')
47 = ('/')
48 = ('0')
49 = ('1')
50 = ('2')
51 = ('3')
52 = ('4')
53 = ('5')
54 = ('6')
55 = ('7')
56 = ('8')
57 = ('9')
58 = (':')
59 = (';')
60 = ('<')
61 = ('=')
62 = ('>')
63 = ('?')
64 = ('@')

As you can see, the ", ', $, &, % and @ are all ok as single entries in the text file. Here is the part of the vartest.txt:

code:

'!'
'"'
'#'
'$'
'%'
'&'
'''
'('
')'
'*'
'+'
','
'-'
'.'
'/'
'0'
'1'
'2'
'3'
'4'
'5'
'6'
'7'
'8'
'9'
':'
';'
'<'
'='
'>'
'?'
'@'

ok, let's talk about Special Characters:

@
KiX and DOS (command prompt in Windows) treat @ in different ways. When KiX sees a @ it looks at the word touching and folloing the @ as a macro. ie @DATE is today's date. DOS, however, treats it as an ordinary character. If you want to output an @ in KiX, you need to @@.

examples from my manual:
@time ; shows the current time
@userid ; shows the user id of the current user
? "Your email address is cj@@email.com" ; prints cj@email.com

$
$ in KiX is used to show a variable. KiX looks at the word following and touching the $, so $abc is a variable and $abc def is only $abc and the def will prob raise an error. To print a $ on the screen or file in KiX you use $$. eg "I want more $$'s"
$ in DOS is a normal character. ie you can rename a file to a$b.txt if you want to.

%
% is used in KiX the same way as in DOS, it signifies an Environment Variable. %path% for example, is the current path. To print a % in KiX use %% eg "over 100%% is lots!" DOS sometimes uses % like KiX uses $
for example: for %a in (*.txt) do DEL %a this will delete all the .txt files in the current directory in DOS, but replacing %a with each .txt filename and running a DEL on it.

' and "
KiX uses both ' and " for quotes, but DOS only uses ". KiX uses quote for two things - as a 'display this text' command or a 'convert this number into a string' command; My manual covers this in greater detail. If you want to display a ' or " on the screen in KiX, you must surround it with the OTHER quote.
For example: To print don't - "don't" and to print "do" - '"do"'. KiX uses the outside quotes (ie the quote that is at the beginning and end) as the command and the inside is the text.

< and >
These are called ReDirectors in DOS and Comparitors (i think) in KiX. DOS uses these to 'redirect' the output of a process to a destination.
for example: DIR normally prints to the screen, but DIR > files.txt will print to a file called files.txt.
DOS uses > the same way KiX uses the REDIRECTOUTPUT() funciton. With the KiX ,0 is the DOS >> and the KiX ,1 is the DOS > (see the manual for more info about REDIRECTOUTPUT() )

< is DOS's reverse redirection. For example, there is a program in the NT4 Resource Kit called CLIP. It allows you to put the contents of a file onto the clipboard by doing this CLIP < yourfile.txt

In KiX < and > are used to test if one value is less than or greater than another. ie IF 1<2 "the universe is at peace" else "cj says 'welcome to my world'" endif

|
This symbol is called Pipe and is used by DOS to send the output of a process to another process.
For example DIR *.txt | find /i "result"
This will run a FIND /i "result" on each line of a DIR *.txt so any files that contain the word result will be displayed. ie result1.txt and 1result.txt. Getting DOS to do this from DIR without help is difficult. (the /i means ignore case)
KiX, however, treats | as a mathematical OR operation.

&
DOS treats & differently depending on the version of DOS you have. Some use it to allow multple commands on one line. eg DIR *.txt & DIR *.exe will do 2 DIRs. KiX uses & in two ways depending on syntax:
1. As a mathematical AND operator eg. $a=3&4
2. To convert a Hexadecimal number to Decimal. "&ff" ; prints 255

I hope I have covered them all.

So, the effects of a ', ", @, $, %, &, <, > or | in KiX and DOS will depend on where they are used and how. In DOS surrounding commands in "" often makes DOS ignore them: ie DIR "*.txt>file.txt" will return "file not found" unless you have a filename with ".txt>file.txt". KiX, however, is not fooled so easily and "@date" is the same as @date. KiX needs to see "@@date" to print the @ as a @.


I hope that as cleared things up a bit, if not, keep asking questions.


Now, changes to the script...

Rather than making a file full of characters, you can use the CHR() function to spit out the character of the number in (). eg CHR(65) is A and chr(97) is a.

When you are making passwords, note that some characters may not be allowed...

copy/paste this URL into ie:

search.microsoft.com/us/SearchMS25.asp?so=RECCNT&qu=characters%2520password%2520%2521&qu=extended+characters+password&boolean=ALL&i=08&i=07&p=1&nq=NEW&fqu=PASSWORD%2526CHARACTERS

Numbers in KiX. If you want to generate all the chars between 32 and 123 inclusive:

KiXtart 3.6x

code:

$i=start
DO
$var=chr($i)
; do your stuff here with $var
$i=$i+1
UNTIL $i=stop+1

or

KiXtart 2001 beta

code:

FOR $i=start TO stop
$var=chr($i)
; do your thing here with $var
NEXT


If you would like a password generator, here is a UDF version. A UDF is a User Defined Function and is new to KiX 2001 beta. Basically you can treat a UDF like a normal KiX function, so UDF(whatever) will print the return result of the UDF to the screen/file, $var=UDF(whatever) will assign the output to a variable, CHR(UDF(whatever)) will print the character whose number is returned by the UDF (this UDF must return a number) etc etc etc...

If you save this to a file called PassGen.UDF, you can access it from any script that has

CALL "\\server\share\PassGen.UDF"

in it. This is because KiX remembers all the UDFs it sees.


PassGen.UDF

code:

PassGen
Author
cj (chrismat@ozemail.com.au)


Action Generates a random alphanumeric password


Syntax PASSGEN([length[,exclude]])


Parameters length
Optional numeric specifying the length of the password. If omitted, the length is set to eight (8).


exclude
Optional string of characters to be omitted from the password returned.


Returns A string of letters and numbers that is length long and does not contain any of the characters in exclude.


Examples passgen() ; returns 8 character alphanumeric string


Passgen(9) ; returns 9 char string


Passgen(6, "0Oo1l5Ss") ; 6 letters, no 0, 1, 5, o, l, s, O or S


Source
Function PassGen(Optional $iLength, Optional $sExclusion)
$PassGen="" ; default password is blank
if not val($iLength) $iLength=8 endif ; default length is 8
dim $i ; setup variables
$i=0
do
$x=rnd(2)
select
case $x=0 $iRND=rnd(9)+48 ; 0..9
case $x=1 $iRND=rnd(25)+97 ; a..z
case $x=2 $iRND=rnd(25)+65 ; A..Z
case 1
endSelect
if not instr($sExclusion, chr($iRND)) ; check exclusion list
$PassGen=$PassGen+chr($iRND)
$i=$i+1
endif
until $i=$iLength
EndFunction


The exclusion of 0, 1, 5, o, l, s, O and S could reduce the number of "my password doesn't work" call to your help desk

If you want to make the password case insensitive, ie a=A then just remove the line ending in ; A..Z from the UDF and change $x=rnd(2) to $x=rnd(1)

If you want to add support for special characters, let me know and I can tell you what to put into the UDF.

Well, that's enough outta me, anything I miss?


cj

------------------
cj's scripts page
cj's User Guide - 14 May 2001

chrismat@ozemail.com.au


[This message has been edited by cj (edited 22 May 2001).]

**DONOTDELETE**
(Lurker)
2001-05-23 12:17 AM
Re: Long post - Special characters within quotes or in variables

Thanks for the information about differences between DOS handling and Kix handling of special characters. I like the UDF too - short, sweet, efficient.

I was reviewing the scripts with a buddy and I decided I had jumped a little soon. By commenting out the shell line and the select case lines in the test script I boiled down the test to just output of characters in Kix. They outputted (word?) just fine. The trouble I run into is outputting the characters generated or read in Kix to a Dos shell. The password.exe command takes all characters typed in on the command line and uses them to change existing passwords. However, when I try to pipe, for instance, existing password lists (so we can change them) we run into the Dos/Kix limitation of how Dos interprets the special characters. I'm not clear whether the limitation is how Kix runs the command shell or whether it lies in how Dos handles the special characters. Regardless, the end result is that I cannot modify existing passwords containing certain special characters.

To further test the interoperability of Kix and Dos shells, I modified the script as follows:

code

variabletest2.kix

$count=""
REDIRECTOUTPUT ("d:\xfile\newgen\result.txt",0)
dim $count
$count=33
do
shell "%comspec% /c echo This is what embedded variable $count looks like: embed" + chr($count) + "test. >>d:\xfile\newgen\resulta.txt"
$count=1+$count
until $COUNT=256
$count=""
EXIT


Here is the sample output...

This is what embedded variable 33 looks like: embed!test.
This is what embedded variable 35 looks like: embed#test.
This is what embedded variable 36 looks like: embed$test.
This is what embedded variable 37 looks like: embed%test.
This is what embedded variable 39 looks like: embed'test.
This is what embedded variable 40 looks like: embed(test.
This is what embedded variable 41 looks like: embed)test.
This is what embedded variable 42 looks like: embed*test.
This is what embedded variable 43 looks like: embed+test.
This is what embedded variable 44 looks like: embed,test.
This is what embedded variable 45 looks like: embed-test.
This is what embedded variable 46 looks like: embed.test.
This is what embedded variable 47 looks like: embed/test.
This is what embedded variable 48 looks like: embed0test.
This is what embedded variable 49 looks like: embed1test.
This is what embedded variable 50 looks like: embed2test.
This is what embedded variable 51 looks like: embed3test.
This is what embedded variable 52 looks like: embed4test.
This is what embedded variable 53 looks like: embed5test.
This is what embedded variable 54 looks like: embed6test.
This is what embedded variable 55 looks like: embed7test.
This is what embedded variable 56 looks like: embed8test.
This is what embedded variable 57 looks like: embed9test.
This is what embedded variable 58 looks like: embed:test.
This is what embedded variable 59 looks like: embed;test.
This is what embedded variable 61 looks like: embed=test.
This is what embedded variable 62 looks like: embed
This is what embedded variable 63 looks like: embed?test.
This is what embedded variable 64 looks like: embed@test.
This is what embedded variable 65 looks like: embedAtest.
This is what embedded variable 66 looks like: embedBtest.
This is what embedded variable 67 looks like: embedCtest.
.
.
.

Note that characters 38 (&), 60 (< ), 62 (> ), and 124 (|) all fail to hand off in a behaved manner.

Also, is it my imagination or did the output characters change from Kix 3.62 to Kix 4.00 (beta 2a). I see several characters that differ from my earlier output file...

Thanks,
Alex

cj
(MM club member)
2001-05-23 10:38 AM
Re: Long post - Special characters within quotes or in variables

>Note that characters 38 (&), 60 (< ), 62 (> ), and 124 (|) all fail to hand off in a behaved manner.

As I said they would, on the command prompt line they are treated differently.

Read this MSKB article: Q103746

It could be that PASSWORD.EXE suffers the same problems.

Tell me what extended chars you would like to use and I will add them to the UDF.

Try this:

$char='"<>|@@$$&%'+"'"
shell "%comspec% /c echo $char"

The KiX var $char contains "<>|@@$$&%', so KiX will print the @@ as @ and the $$ as $ when it sends this to the command line.

What chars would you like to use in the password?


A quick idea...

code:

break on cls


; This script will show you the differences between:
;
; 1. Writing to a File with KiX OPEN, WRITELINE, CLOSE
; 2. Writing to a File with KiX REDIRECTOUTPUT
; 3. Writing to a File with SHELL and ECHO
; 4. Writing to the Screen with SHELL and ECHO


del "result1.txt"
$=open(1, "result1.txt", 5)


$=redirectoutput("result2.txt", 1)


$count=33 ; start character
do
$char=chr($count) ; get string version


$=writeline(1, "This char is number $count and looks like this $char"+chr(13)+chr(10)) ; 1.


"This char is number $count and looks like this $char" ? ; 2.


; These DOS commands must be enclosed in double quotes otherwise they will activate
if $char="<" or $char=">" or $char="|" or $char="&" or $char="^"
$char='"'+$char+'"'
endif


; use this to make " become ""
;if $char='"' $char='""' endif


shell '%comspec% /c echo This char is number $count and looks like this $char >>result3.txt 2>>errors.txt' ; 3


shell "%comspec% /c echo This char is number $count and looks like this $char" ; 4


$count=$count+1 ; next char
until $count=256


$=close(1) ; close file 1



cj

------------------
cj's scripts page
cj's User Guide - 14 May 2001

chrismat@ozemail.com.au