Command Prompt Scripting & Security

Mirza Leka
14 min readMar 27, 2023

--

In the final chapter of this CMD series, we’ll focus on security and writing code. We’ll learn how to protect data, write Batch Scripts, run C# apps with CMD, make CURL calls, set environment variables, and summarize what we’ve learned so far.

Matrix photo by Markus Spiske from Pexels. Windows edit my own

If you’re new to the series you may be interested in the previous chapters.

Photo by Life Of Pix from Pexels

Secure Personal Data

In this module, we’ll learn how to protect our data with CMD by hiding, encrypting, and locking files and folders as well as changing a password securely.

Encrypt & Decrypt data

Encryption is used to prohibit other users to see the contents of the files.

Supposedly we have a passwords.txt file on our machine that no one is allowed to see but us, we can use a command line utility cipher to encrypt this file.

important> cipher /e passwords.txt

Encrypting files in C:\Users\Mirza\Desktop\important\
passwords.txt [OK]

Looking at the same file now a lock should pop up on the icon.

Since we set the encryption we can, of course, open the file, but any other user on this machine, or user that connects to the machine won’t be able to.

To decrypt the file we once again make use of the cipher command. Only this time instead of passing the flag e/(encrypt), we use /d (decrypt) flag.

important>cipher /d passwords.txt

Decrypting files in C:\Users\Mirza\Desktop\important\
passwords.txt [OK]

And just like that, the file is decrypted and the lock is gone.

We can also encrypt files from the outside. If we execute cipher against the directory, all files inside will be encrypted.

C:\Users\Mirza\Desktop>cipher /e important

Encrypting files in C:\Users\Mirza\Desktop\

important [OK]

1 file(s) [or directorie(s)] within 1 directorie(s) were encrypted.

And the lock should appear on the directory icon.

The same goes for decryption.

Hide files and folders

Even with encryption, the file we locked is still visible in explorer. To hide the directory or the file we make use of attrib command followed by a few options and a path to the directory/file we want to hide.

> attrib +s +h passwords.txt

And the passwords.txt file that was previously here is gone.

We can’t even see it if we run the standard dir command in the CMD.

C:\Users\Mirza\Desktop\imporant>dir

03/26/2023 8:39 PM <DIR> .
03/26/2023 8:39 PM <DIR> ..
0 File(s) 0 bytes

Even if we toggle an option to display hidden files and folders, the file won’t be there.

Let’s clarify what this command meant.

  • attrib — attributes
  • + — we’re adding an attribute
  • s — system files
  • h — hide

The only way the file will display is if we use a dir variant that displays even the hidden files/folders. (dir /a displays all files)

C:\Users\Mirza\Desktop\imporant>dir /a

03/26/2023 8:39 PM <DIR> .
03/26/2023 8:39 PM <DIR> ..
03/26/2023 8:39 PM 0 passwords.txt

To reverse this we type the same command just this time we use minuses instead of pluses.

> attrib -s -h passwords.txt

And the file is back.

The same works for folders as well.

Create secured directories

Secure directories cannot be copied, moved, or deleted. To do that create a directory called aux\(Auxiliary device — protected name in MS-DOS)

Desktop>mkdir aux\

We can put data in this folder but only from the outside.

Entering this directory via CMD is not possible as CMD complains that the directory is not present.

Desktop>cd aux
The system cannot find the path specified.

If we try to delete the directory, Windows will pop up a message that the directory is not found even though it’s right in from of us.

The only way to remove such a directory is through the terminal.
Make sure that the aux\ folder is empty before deleting it.

Desktop>rmdir aux\

Lock Files and Folders

Similar to encryption we can set permissions per file/folder that will prevent anyone from opening or editing them.

Desktop>cacls secrets /P everyone:n
Are you sure (Y/N)?y
processed dir: C:\Users\Mirza\Desktop\secrets

If we try to open the secrets folder we should get a warning.

The file is locked. Let’s explain what this command did:

  • cacls / icacls — CMD utility for access lock control (ACL)
  • secrets — path, directory, or file name we want to lock
  • /P — permissions we want to set
  • everyone: flag — what permissions users have

Permissions variations:

  • n — None
  • r — Read (read-only)
  • c — Change (read and write)
  • f — Full control (no locks)

So the command we ran:

> cacls secrets /P everyone:n

Prohibits anyone to access the secrets directory.
To clear this out we run the same command with :f flag at the end.

C:\Users\Mirza\Desktop>cacls secrets /P everyone:f
Are you sure (Y/N)?y
processed dir: C:\Users\Mirza\Desktop\secrets

The folder is now fully accessible.
Inside the secrets folder, there is a file called secret keys. I’ve already run a lock on it to set it to read-only.

> cacls secret-keys.txt /P everyone:r

If we attempt to edit this file and save our edits in the existing file, Windows will complain that we do not have permission to do so.

Permissions can be reset the same way as above.

C:\Users\Mirza\Desktop\secrets>cacls secret-keys.txt /P everyone:f
Are you sure (Y/N)?y
processed file: C:\Users\Mirza\Desktop\secrets\secret-keys.txt

Change Password with CMD

Using the net command we can change the password of our Windows user through the Command Prompt. First, let’s list all users:

Desktop>net user

User accounts for \\DESKTOP

------------------------------------------------------------------
Administrator DefaultAccount Mirza
Guest WDAGUtilityAccount

The command completed successfully.

Suppose we want to change the password for one of our users. There are two ways to do this.

The first way is to type out net user <username> <password> :

> net user Mirza 1234

The command completed successfully.

This of course sets a password for our user that it will use to log in next time. However, this was anything but secure. To keep our input hidden we’ll use the second option.

For the second case, we’ll type almost everything the same, but when we get to the password we’ll just type an asterisk and hit enter.

> net user Mirza *

This will pop up additional questions. If we enter the password now the text we enter will not be visible on CMD.

> net user Mirza *
Type a password for the user:
Retype the password to confirm:
The command completed successfully.

The password is set again.

To remove the password, follow the same steps as above and hit enter twice when prompted (do not enter anything).

Photo by Negative Space from Pexels

CURL

The Client for URL (CURL) is a tool for transferring data with URLs. The power of Postman in the Command Prompt. With CURL we can send HTTP requests to the servers directly from CMD.

GET Request

Let’s start by retrieving information from the server. Enter curl followed by the URL and it should return the response.

> curl www.google.com

CURL on the Google page returns a whole bunch of HTML.

Other endpoints return other responses, like files to download, XML, or JSON. Here is another request that returns a dummy JSON object:

> curl https://jsonplaceholder.typicode.com/users/1

API response:

{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874",
"geo": {
"lat": "-37.3159",
"lng": "81.1496"
}
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
}

We can save the response content into a file using the output flag > followed by the name of the file.

> curl https://jsonplaceholder.typicode.com/users/1 > response.json

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 509 100 509 0 0 3029 0 --:--:-- --:--:-- --:--:-- 3047
The response is saved into a file on the machine

HEAD Request

The HEAD request is similar to GET, with one exception — it only returns the headers from the server. To specify this request type we use the -I flag when performing CURL.

> curl https://jsonplaceholder.typicode.com/users/1 -I

POST Request

To create new content using CURL we can make use of a POST request.
We use -X flag to specify the request type (GET / POST / PUT, etc.), followed by content-type -H (in this case JSON), then --data flag containing the data we’re sending.

curl -X 'POST' -H 'Content-Type: application/json' --data 
'{"name":"mirza", "profession":"dev"}' https://some-API/

And the server will send us the response.

Read more on CURL.

Photo by Khizar Hayat from Pexels

Common Script Commands

Let’s take a quick peek into some of the commands we haven’t used yet.

Time and Date

We can get the current time with %TIME% command combined with the echo command to print it out.

> echo %TIME%
> 07:42:49.64

And for the current date:

> echo %DATE%
> Mon 03/27/2023

We can combine two in one line.

> echo %DATE% %TIME%
> Mon 03/27/2023 07:43:46.04

Environment Variables

The percentage symbols around a word indicate a variable name. We can use it to print out any environment variable, e.g. computer username:

> echo %USERNAME%
> Mirza

> echo %USERPROFILE%
> C:\Users\Mirza

We can also create our own variables using the set keyword:

> set num=123

And print it with echo:

> echo %num% 
> 123

If we once again set a value of the variable, it will override the previous value.

> set num=45
> echo number is: %num%
> number is: 45

Now let’s declare a variable that contains a string (text):

> set coming_soon=Angular article
> echo %coming_soon%

Notes:
Don’t use spaces when setting variables, e.g. : set num = 123because that won’t work.
When declaring variables containing strings, we do not wrap words quotes.

Path

Displays the path variable (collection of environment variables).

Desktop> path

PATH=C:\Program Files (x86)\Common Files\Oracle\Java\javapath
;C:\Windows\system32;
...

Other common commands.

Photo by Sora Shimazaki from Pexels

Batch Scripting

Rather than executing each command line by line in the Command Prompt, we can create a Batch file that can contain several. Batch Scripts are stored in simple text files containing lines with commands that get executed in sequence, one after the other.

Upon writing a script file, we can execute it at any time.
The term “batch” is from batch processing, meaning “non-interactive execution”.

First Batch Script

To create a batch script we need to create a .bat file. It can be done with a right button click or via CMD, e.g.: first-script.bat

Inside we’ll write our script:

@echo off
echo Hello World!

The @echo off command hides script code from CMD when the script is been executed.

To run this script we can double-click on it (first-script.bat) or via CMD:

> first-script.bat
Response from our script

Works like a charm!

Arithmetic operations

Moving forward we can create a super simple calculator script that performs arithmetic operations, such as addition, subtraction, multiplication, and division.

This is a script that calculates the sum of two numbers.

@echo off
set var1=2
set var2=3

set /a sum= %var1% + %var2%
echo sum is: %sum%

In order for the sum to work we added /a that stands for arithmetic.
When executed, it will always print the sum of 2 & 3;

> sum.bat
> sum is: 5

To make this truly work like a calculator we can pass the arguments when executing a script. First, we need to update our script to pick up values from the Command Prompt.

@echo off
set var1=%1
set var2=%2

set /a sum= %var1% + %var2%
echo sum is: %sum%

Where,
%1 represents the first argument passed in
%2 is the second

%2 is the second

> sum.bat 20 30
> sum is: 50

> sum.bat 8 7
> sum is: 15

Conditions

Here is another script that looks up a specific file in folder2. If the file already exists, the script removes it. Otherwise, it goes to the else case and creates a new file.

@echo off

IF EXIST folder2\file.txt (
echo File already exists!
del folder2\file.txt
echo File removed!
) ELSE (
echo File not found!
cd. > folder2\file.txt
echo New file generated.
)

Full list of conditions commands.

Goto

The GOTO command is used when we want to off-road the script execution. As an example, we can say if the script is missing an argument throw an error to the consumer. Otherwise, run as usual.

In this example, we’re reading contents from the file located on our machine. The directory path is already set, but we need to pass the name of the file we want to preview (via type command). If we leave out the file name, the Command Prompt will go to the :error case and complain that the file name is not provided.

@echo off

set folder_path="C:\Users\Mirza"

if "%1" == "" goto :error

set file_name=%1

IF EXIST %folder_path%\%file_name% (
type %folder_path%\%file_name%
) ELSE (
echo File not found!
)

goto :eof

:error
echo File name is not provided!

And if the file name is provided but does not exist in the specified directory path, it will print the message that the file was not found.

Because we set up goto for the error case, for the different path, we need to use goto :eof command (end of file) to reroute the script. It basically tells CMD that it can exit the script.

> goto-script.bat file.extension

Loops

Loops repeat a certain action over multiple iterations. We can make use of loops to create multiple folders at once.

@echo off
FOR /L %%G IN (1,1,5) DO (
mkdir test%%G
)

Rem This is a comment

Where

  • 0 represents the starting index
  • 1 is the counter index (count increases by one for each iteration)
  • 4 is the final iteration count

This will create 5 distinct folders in our directory where each folder will be called test followed by the iteration index (%%G).

> loop.bat

> dir

03/26/2023 05:08 PM <DIR> test0
03/26/2023 05:08 PM <DIR> test1
03/26/2023 05:08 PM <DIR> test2
03/26/2023 05:08 PM <DIR> test3
03/26/2023 05:08 PM <DIR> test4

Express.js server via Batch Scripts

This script will create and set up the Express.js API server by creating a project directory, installing all required packages, and generating an app.js file by inserting line by line into the file.
To put this in motion, you need to have Node.js installed on your PC.

echo [LOG]: Setting up project directory...

mkdir express-app & cd express-app

echo [LOG]: Setting up server file...

echo const express = require('express'); >> app.js

echo const app = express(); >> app.js

echo const notifier = require('node-notifier'); >> app.js

echo app.get('/', (req, res) =^> { res.send('Hello World!') }) >> app.js

echo app.listen(4000, () =^> console.log('server started on localhost:4000')); >> app.js

echo notifier.notify({ title: 'Server is running!', message: 'Please visit localhost:4000', wait: false }) >> app.js

echo [LOG]: Installing packages...

npm init -y & npm i express node-notifier & node app.js

Here we’re using the caret symbol (^) to escape greater than (>) characters.
When we run this script via CMD or double-click on the .bat file, it should start an Express.js server on pc.

To verify that this works, we can open up another CMD and use CURL to invoke the request on port 4000.

> curl localhost:4000
The response coming from the Express.js server using CURL

We can terminate the Express app by hitting CTRL+C in the Express CMD or closing the CMD altogether.

Photo by WakeUpAndCode.com

Running .NET applications with CMD

Using the CSC (C# Compiler) we can compile and run C# apps without using a solution file from an IDE (such as Microsoft Visual Studio or Jetbrains Rider). CSC is executed directly from Command Prompt.

Let’s create a C# Hello World program.

using System;

public class Program
{
public static void Main()
{
Console.WriteLine("Hello C#");
}
}

If we were to run this file directly, Windows would not be sure how to and prompt us with possible answers.

But this is not what we want. We want to compile it through CMD. For that let’s use the previously mentioned csc command.

Desktop> csc program.cs

And voila, we have compiled a program.cs file into a program.exe file.
Watch this if you have issues with running the CSC command.

Desktop>dir

Directory of C:\Users\Mirza\Desktop

03/25/2023 10:13 AM 118 program.cs
03/25/2023 10:19 AM 3,584 program.exe

Now we run the .exe file through the CMD.

Desktop> program.exe

And it worked! How cool was that?

Photo by icon0.com from Pexels

Summary

Let’s quickly go over some of the commands we’ve used in this series:

  • mkdir — create a directory
  • rmdir — remove a directory
  • cd — navigate between directories and drives
  • dir, tree — list out folders and files
  • cls — clear Command Prompt
  • esc — cancel command
  • start — run executables
  • /? — list of options that can be applied to a command
  • & — command break. Used to execute Multiple commands in a line
  • echo — print or insert text
  • “ “ — wrap text within quotes whenever you have words with space in between
  • ipconfig — list IP addresses
  • set — create a variable

As mentioned before, we can execute commands in whichever casing we like, but we can’t have files in the same directory having the same names even if the casing is different.

Code, Commit, Deploy

When it comes to using third-party tools, such as Git, NPM, AWS-CLI, etc, the commands you type in CMD are the same as those in the Unix terminal.

  • Git git add, git commit, git pull/push
  • Nginx start nginx, nginx -s reload
  • Docker docker run hello-world, docker build .
  • Node.js node app.js, npm i, npm init -y
  • .NET dotnet new, dotnet run
  • Secure Shell ssh ip

The only difference is that we don’t type sudo.

Wrapping Up

This is where this series ends but it is not the end of the Command Prompt. We only scratched the surface of shells can do. I also recommend you try the Unix terminal as it has far greater capabilities. However, if you’re interested to learn more about CMD, be sure to check the section below.

Learn More

Other Command Prompt apps that can be used on a Windows machine:

  • Chocolatey
  • Commander
  • Powershell
  • Git Bash

--

--

Mirza Leka
Mirza Leka

Written by Mirza Leka

Web Developer. DevOps Enthusiast. I share my experience with the rest of the world. Follow me on https://twitter.com/mirzaleka for news & updates #FreePalestine

No responses yet