By: Nisarg Upadhyay | Comments (26) | Related: > PowerShell
Problem
In this tip we will walk through how to create a PowerShell module to get a list of files and subfolders of a Windows folder and store this information in a SQL Server table.
Solution
In this tip, I am going to explain the code of a PowerShell module which gets a list of files that reside in a folder and stores this information in a SQL Server table.
I am going to:
- Create a SQL table that has a column to store FQN (Fully qualified name) of any file.
- Show how to write the PowerShell code.
- Execute PowerShell function using T-SQL.
In this tip, I have used the following PowerShell cmdlets.
PowerShell cmdlet | Description |
---|---|
Invoke-SQLCmd | It is used to execute a SQL command. Reference: Invoke-SQLcmd |
Get-ChildItem | It gets a list of files in a specified location. Reference: Get-ChildItem. |
Foreach-Object | It iterates through the collection of items and performs operations against each item. Reference: Foreach-Object |
Create the SQL Server Table
To store the directory contents in a table, first I will create a table named "tblFileLocations" in database "DemoDatabase". The following code creates the SQL table.
USE DemoDatabase GO CREATE TABLE [dbo].[tblFileLocations]( [ID] [int] IDENTITY(1,1) NOT NULL, [File_name] [varchar](max) NULL, [FileLocation] [varchar](max) NULL, [CreateDate] varchar(50) NULL, [LastChangeDate] varchar(50) NULL, [FileSize] [numeric](10,5) NULL, PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO
Create a PowerShell Module
As I mentioned, I want to get the list of files within a specific directory. To do that, we will create a PowerShell cmdlet. It accepts the Drive Letter as a parameter, iterates through the entire drive and populates the following details:
- File Name
- Fully qualified file name
- File attribute
- Last access time
- Last modified time
- File Size
To execute this function using a SQL Stored procedure, we must register it as a PowerShell module. Once the PowerShell module is registered, we add this module in the PowerShell profile.
First, let’s understand the PowerShell script.
To understand the PowerShell code, I have split it into multiple sections:
Script Part-1
Create a PowerShell function. This function accepts the Drive Letter as a parameter. The following code block creates the function.
function global:getFileLocations { param( [Parameter(Position=0,mandatory=$true)] [string[]] $FileLocation ) }
Script Part-2
Construct a string variable named "$sqlstatment" that has an "Insert" query statement. The following code creates a string variable.
$sqlstatement=@' INSERT INTO tblFileLocations ( File_name, FileLocation, CreateDate, LastChangeDate, FileSize ) VALUES ( '{0}', '{1}', '{2}', '{3}', '{4}' ) '@
Script Part-3
Populate list of files command and formats the output according to the insert query stored in the "$sqlstatement" variable. The following is the code block.
Get-ChildItem -Recurse $FileLocation | select Name,FullName,CreationTime, LastWriteTime, @{Label="Length";Expression={$_.Length / 1KB -as [int] }} | ForEach-Object { $SQL = $sqlstatement -f $_.name,$_.FullName, $_.CreationTime,$_.LastWriteTime,$_.Length Invoke-sqlcmd -Query $SQL -ServerInstance “TTI412-VM\SQL2017” -database “DemoDatabase” }
The above code block performs the following tasks:
- It passes "$FilePath" parameter to "Get-ChildItem -Recurse" cmdlet and populates the list of files. "$FilePath" parameter is drive letter/ directory location (C:\Temp\...).
- Format the output, generated by "Get-ChildItem -Recurse" in multiple columns. Column sequence of output and the insert statement which is stored in "$sqlstatement" parameter must be the same.
The output of "Get-ChildItem -Recurse" | Column sequence in the insert query |
---|---|
FullName | {0} |
Name | {1} |
CreationTime | {2} |
LastWriteTime | {3} |
FileSize | {4} |
- It creates a new string variable named "$SQLQuery" by concatenating "$sqlstatement" and the values generated by "Get-ChildItem -Recurse" command. The format of "$SQLQuery" parameter is like a T-SQL insert statement. Using "ForEach-Object" cmdlet, it generates multiple insert statements and stores it in a $SQLQuery variable. See the following image:
- By using "Invoke-SQLCmd" command, it inserts the value of the $SQLQuery variable into the tblFileLocations table.
Complete PowerShell Script
function global:getFileLocations { param( [Parameter(Position=0,mandatory=$true)] [string[]] $FileLocation ) Write-Output "Inserting File Locations in table" $sqlstatement=@' INSERT INTO tblFileLocations( File_name,FileLocation,CreateDate,LastChangeDate,FileSize ) VALUES ( '{0}', '{1}', '{2}', '{3}', '{4}' ) '@ Get-ChildItem -Recurse $FileLocation | select Name,FullName,CreationTime, LastWriteTime, @{Label="Length";Expression={$_.Length / 1KB -as [int] }} | ForEach-Object { $SQL = $sqlstatement -f $_.name,$_.FullName, $_.CreationTime,$_.LastWriteTime,$_.Length Invoke-sqlcmd -Query $SQL -ServerInstance “TTI412-VM\SQL2017” -database “DemoDatabase” } Write-Output "File locations are saved in table" }
Save Script as a PowerShell Module
To execute the PowerShell function using T-SQL, register this script as PowerShell module. To register any PowerShell script, first a directory must be created in "C:\Windows\System32\WindowsPowerShell\v1.0\Modules". The name of the PowerShell script and directory must be the same. To register the above script, perform the following tasks:
- Create a new directory named "getFileLocations" in "C:\Windows\System32\WindowsPowerShell\v1.0\Modules" directory.
- Save the PowerShell script as getFileLocations.psm1 in "getFileLocations" directory.
Execute the PowerShell Function in T-SQL Script
To execute a PowerShell function in a stored procedure, enable xp_cmdshell. To do that, execute the following command:
use master go exec sp_configure 'show advanced option',1 reconfigure with override exec sp_configure 'xp_cmdshell',1 reconfigure with override
To execute the PowerShell script using a T-SQL query, use the "powershell.exe" command. As I mentioned, our script inserts the fully qualified path of files located in a specific drive or specific directory, hence we must create a parameterized T-SQL script. In the script, we can pass the drive letter OR directory path as a parameter.
For this demonstration, I created a folder named "UPADHYAY ALBUM"" in my E drive. I copied a few SQL scripts to the folder. I am going to insert the file details of all directories and files located in the E:\UPADHYAY ALBUM\ folder. To do that, execute the following code:
declare @PSScript varchar(2500) declare @FileLocation varchar(2500) set @FileLocation='D:\UPADHYAY ALBUM' set @PSScript= 'powershell.exe getFileLocations ''' + @FileLocation +'''' exec xp_cmdshell @PSScript
Let’s verify that whether file details are stored in a table using the following code:
SELECT * FROM tblFileLocations
As you can see in the following output, the fully qualified names and details from the "E:\UPADHYAY ALBUM\" directory is stored in the "Fully_Qualified_FileName" " column.
Summary
In this article, I explained:
- How to create a PowerShell module and how the PowerShell script works.
- Execute the PowerShell function using T-SQL code.
Next Steps
- Check out these other PowerShell tips
About the author
This author pledges the content of this article is based on professional experience and not AI generated.
View all my tips