Passing path parameter into power shell script using batch file - powershell

I would like to pass in a path variable --> param ([string]$w) into another parameter that store the path in power shell script. Then this power shell script is called using another batch file. I failed to pass in the $ which is the folder name that completes the full path . Please suggest me solution on this
$FilePath = "C:\Root\Main\Subfolder\param ([string]$w)\Table\"
$FileExists = Test-Path $FilePath
If ($FileExists -eq $True)
{ Get-ChildItem -path C:\Root\Main\Subfolder\param ([string]$w)\Table\ -Recurse -Filter *.sql |
` Sort-Object -Property DirectoryName -Desc | `
Foreach-Object -Process {$_.FullName } |ForEach-Object {sqlcmd -i $_}
}
Else {Write-Host "No file at this location"}
This is my batch file command line
PowerShell.Exe -File C:\Users\AZ\Desktop\PowerShell\untitled7.ps1 "Payment"

Try putting this at the top of your script:
param(
[Parameter(
Mandatory=$true,
Position=0,
HelpMessage='Set path variable')]
[string] $w
)
Replace:
param ([string]$w)
with:
$w
where it appears in your script.

Related

Why doesn't the full directory name display when passing an exclude parameter which passes it to a for loop to display?

So, I actually don't believe that its the string value I'm passing to the parameter that is the issue, I think its how my for loop is displaying it.
Function Get-Users{
[cmdletbinding()]
Param(
[Parameter(Mandatory=$false,
ValueFromPipeLine=$true,
ValueFromPipeLineByPropertyName=$true,
HelpMessage='Enter Computer Name')]
[Alias('CN','Computer','Name')]
[ValidateLength(1,15)]
[string]$ComputerName = $env:COMPUTERNAME,
[Parameter(Mandatory=$false,
ValueFromPipeLine=$true,
ValueFromPipeLineByPropertyName=$true)]
[String]$Exclude
)
$UNC = Get-ChildItem -Path \\$ComputerName\c$\Users -Exclude $Exclude -Directory | Select-Object -ExpandProperty Name | Sort-Object -Descending
for($i=0; $i -lt $UNC.Count; $i++){
"$($i): $($UNC[$i])" }
""
$SS = Read-Host -Prompt "Enter # of user(s)"
$s = $SS -split " "
foreach($user in $UNC[$s]){
"$User" }
}
I feel like this should work as it does when I do it when just running it in the console like so: Get-ChildItem -Path C:\users -Exclude "Abraham" -Directory; It simply excludes my directory listing.
Even when nothing is specified in the parameter it still runs just fine: Get-ChildItem -Path C:\users -Exclude "" -Directory in regards to listing all directories, but when I pass it using my self-made parameters it doesn't display correctly. What I get instead is the following:
PS > Get-Users -Exclude Abraham
0: P
Enter # of user(s):
When it should be:
PS > Get-Users -Exclude Abraham
0: Public
Enter # of user(s):
Can someone educate me on why it doesn't display the full Directory name?
Please note that itll list all directories when the -Exclude Parameter isn't specified.
Change this $UNC = Get-ChildItem -Path \\$C...... for this $UNC = #(Get-ChildItem -Path \\$C......) or this [array]$UNC = Get-ChildItem -Path \\$C.......
The problem is that you're getting just one result from gci, because of that the variable is a string and not an array, hence when calling the position 0 of your string you're getting the first letter of the string and not the first element of your array :)
PS /~> $unc=(gci *.txt).Name
PS /~> for($i=0; $i -lt $unc.count; $i++)
{
"$($i): $($UNC[$i])"
}
0: t
PS /~> [array]$unc=$unc
PS /~> for($i=0; $i -lt $unc.count; $i++)
{
"$($i): $($UNC[$i])"
}
0: test.txt

Searching with Get-ChildItem over the network

I'm having an issue while searching with PowerShell over the network; program get stuck while executing Get-ChildItem.
# creating search string
$date = "*2018-01-10*"
$format = ".avi"
$toSearch = $date + $format
echo $toSearch
# Verifying A: drive to be disconnected
net use /d A: /y
# connecting Network drive to local drive A:
if (Test-Connection -ComputerName PROC-033-SV -Quiet) {net use A: \\PROC-033-SV\c$}
# getting list of directories to search on
$userList = Get-ChildItem -Path A:\users\*.* -Directory
# verifying list of directories prior to search
echo $userList
# searching through Network, on A:\Users\ subdirectories for $toSearch variable
Get-ChildItem -Path $userList -Include $toSearch -Recurse -Force
# *** HERE's where the program get stuck, it nevers stop searching
# it nevers reach pause
pause
Does anyone know why Get-ChildItem keeps looping and it never stops?
I'm using PS v4 no -Depth option available for -Recurse parameter; I'm suspecting that might be the issue.
If you want to limit recursion depth in PowerShell v4 and earlier you could wrap Get-ChildItem in a custom function, e.g. like this:
function Get-ChildItemRecursive {
[CmdletBinding()]
Param(
[Parameter(
Mandatory=$false,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true
)]
[string[]]$Path = $PWD.Path,
[Paramter(Mandatory=$false)]
[string]$Filter = '*.*',
[Parameter(Mandatory=$false)]
[int]$Depth = 0
)
Process {
Get-ChildItem -Path $Path -Filter $Filter
if ($Depth -gt 0) {
Get-ChildItem -Path $Path |
Where-Object { $_.PSIsContainer } |
Get-ChildItemRecursive -Filter $Filter -Depth ($Depth - 1)
}
}
}

Replace command in powershell is deleting the whole content

I am new to powershell. I create a powershell script which need to search a string in the path provided in parameters and replace that string. But actually it is replacing entire file content with new string.
I am using Powershell in Windows 10 OS.
Code:
param(
[Parameter(Mandatory=$true, ParameterSetName="Path", Position=0,HelpMessage='Data folder Path')]
[string] $Path,
[Parameter(Mandatory=$true, HelpMessage='Input the string to be replaced')]
[string] $Input,
[Parameter(Mandatory=$true,HelpMessage='Input the new string that need to be replaced')]
[string] $Replace
)
$a = Test-Path $Path
IF ($a -eq $True) {Write-Host "Path Exists"} ELSE {Write-Host "Path Doesnot exits"}
$configFiles = Get-ChildItem -Path $Path -include *.pro, *.rux -recurse
$Append = join-path -path $path \*
$b = test-path $Append -include *.pro, *.rux
If($b -eq $True) {
foreach ($file in $configFiles)
{
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace [regex]::Escape($Input), $Replace } |
Set-Content $file.PSPath
}
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("Operation Completed",0,"Done",0x0)
}
As best I can read this without directly reproducing it, this is where it goes wrong:
(get-content $file.pspath) gets the entire content of the file, not its name.
Your "foreach" then regexes every line in the file, and finally "set-content" replaces the contents of the file, not its path.
If you want to change the name of a file, you are looking for Rename-Item, not Set-Content. If you want the name of a file $file.Name will do, you don't need Get-Content, which will ... get its content :)
This should be a working solution.
Param(
[Parameter(Mandatory,
ParameterSetName='Path',
Position=0,
HelpMessage='Data folder Path')]
[String]
$Path,
[Parameter(Mandatory,
HelpMessage='Input the string to be replaced')]
[String]
$StringToReplace,
[Parameter(Mandatory,
HelpMessage='Input the new string that need to be replaced')]
[String]
$ReplacementString
)
If (!(Test-Path $Path)) {
Write-Host 'Path does not exist'
Return
}
Get-ChildItem -Path $Path -Include *.pro,*.rux -Recurse |
? { $_.Name -like "*$StringToReplace*" } |
% { Rename-Item $_ $($ReplacementString+$_.Extension) }
(New-Object -ComObject Wscript.Shell).Popup("Operation Completed",0,"Done",0x0)

Powershell proper way to pass object to function

I am trying to list all msi files found in a given dir to a file, then extract those msi files. I am trying to use the $_ in the foreach-object to pass the path however it seems to be interpreting it as a literal, instead of passing the path. I thought the $_ would pass the object, which in this case would be the filepath, but it doesnt seem to be functioning that way. What is the proper way to pass the found filepaths to the Export-MsiContents function?
Function Export-MsiContents
{
[CmdletBinding()]
param
(
[Parameter(Mandatory = $true, Position=0)]
[ValidateNotNullOrEmpty()]
[ValidateScript({Test-Path $_})]
[ValidateScript({$_.EndsWith(".msi")})]
[String] $MsiPath,
[Parameter(Mandatory=$false, Position=1)]
[String] $TargetDirectory
)
if(-not($TargetDirectory))
{
$currentDir = [System.IO.Path]::GetDirectoryName($MsiPath)
Write-Warning "A target directory is not specified. The contents of the MSI will be extracted to the location, $currentDir\Temp"
$TargetDirectory = Join-Path $currentDir "Temp"
}
$MsiPath = Resolve-Path $MsiPath
Write-Verbose "Extracting the contents of $MsiPath to $TargetDirectory"
Start-Process "MSIEXEC" -ArgumentList "/a $MsiPath /qn TARGETDIR=$TargetDirectory" -Wait -NoNewWindow
}
$Dir = get-childitem d:\temp\test -recurse
$List = $Dir | where {$_.extension -eq ".msi"}
$List | format-table fullname | out-file d:\temp\test\msilist.txt
$List | ForEach-Object {Export-MsiContents -MsiPath $_}
It looks like you are trying to specify a childitem object as the $MsiPath which should be a string.
So you would need to specify which value in that object to use as $MsiPath. In this case it looks like you would like to pass the fullname.
Try this:
$List | ForEach-Object {Export-MsiContents -MsiPath $_.fullname}

How to create several zip folders (function) from my output?

I am trying to zip all folders I find in my folder called services.
I use Get-Childitem to find these folders and I want to add the function after the pipeline, but it doesn't work out the way I want.
The zip file should have the same name as the folder itself, so I tried to give the name with "$.FullName" and destinationpath is the folder "C:\com\$.Name"
Here is my script :
Get-ChildItem "C:\com\services" | % $_.FullName
$folder = "C:\com\services"
$destinationFilePath = "C:\com"
function create-7zip([String] $folder, [String] $destinationFilePath)
{
[string]$pathToZipExe = "C:\Program Files (x86)\7-Zip\7zG.exe";
[Array]$arguments = "a", "-tzip", "$destinationFilePath", "$folder";
& $pathToZipExe $arguments;
}
First. Declare variables like folder and destination path.
Second. Change your 7zip folderpath as mine is in (Program Files).
#declare variables
$folder = "C:\com\services"
$destPath = "C:\destinationfolder\"
#Define the function
function create-7zip{
param([String] $folder,
[String] $destinationFilePath)
write-host $folder $destinationFilePath
[string]$pathToZipExe = "C:\Program Files\7-Zip\7z.exe";
[Array]$arguments = "a", "-tzip", "$destinationFilePath", "$folder";
& $pathToZipExe $arguments;
}
Get-ChildItem $folder | ? { $_.PSIsContainer} | % {
write-host $_.BaseName $_.Name;
$dest= [System.String]::Concat($destPath,$_.Name,".zip");
(create-7zip $_.FullName $dest)
}
$_.PSIsContainer will find only the folders, constructing destination path variable $dest and then calling the function. I hope this helps.
If I understand you correctly, you want to pipe the output of gci into your Create-7Zip function, and have the function create a zip file named after each directory you're passing in, like this:
gci | ?{ $_.PSIsContainer } | Create-7Zip
To do this you'll need the cmdlet you're writing to support taking values from the pipeline, which you do with a [Parameter] attribute in your list of params().
function Create-7Zip
{
param(
[Parameter(ValueFromPipeline=$True)]
[IO.DirectoryInfo]$Directory #we're accepting directories from the pipeline. Based on the directory we'll get the zip name
);
BEGIN
{
$7Zip = Join-Path $env:ProgramFiles "7-Zip\7z.exe"; #get executable
}
PROCESS
{
$zipName = $("{0}.zip" -f $Directory.Name);
$7zArgs = Write-Output "a" "-tzip" $zipName $directory.FullName; #Q&D way to get an array
&$7Zip $7zArgs
}
}
Usage:
#Powershell 3.0
get-childitem -directory | Create-7Zip
#Powershell 2
get-childitem | ?{ $_.PSIsContainer } | Create-7Zip
You'll see the output of 7zip; you can capture this information by piping it to somewhere else.