How to write old VB Commands in Powershell - powershell

I want to write some old VB into PS, however there are some old DOS commands here that I am struggling to write into powershell. For instance, I want to delete files from an Archive, and the way its written in VB is:
command=(%comspec% /C DEL C:\\MyFile.txt",0,True)
If result <> 0 then
txtFile.writeline "ERROR"
txtFile.writeline "File does not exist.."
result = 0
Else
txtFile.writeline "Success"
End if
In Powershell, The /C DEL is the line I'm having trouble writing. How would I write this command in powershell or would I just ignore it completely and just carry on with my IF statement?
Thanks,

In powershell, just use Remove-Item. This mimics your VB pretty well:
try {
Remove-Item 'C:\MyFile.txt' -Force -ErrorAction 'Stop'
Write-Host 'Success'
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Host 'ERROR'
Write-Host 'File does not exist..'
}
Of course, there's a dozen ways this cat can be skinned:
if (Test-Path 'C:\MyFile.txt') {
Remove-Item 'C:\MyFile.txt' -Force
Write-Host 'Success'
} else {
Write-Host 'ERROR'
Write-Host 'File does not exist..'
}
There's definitely more options out there ...

Related

Running a batch file through powershell with content from a text file

I am hoping someone can help me on this, I have a script that Removes and updates FSRM groups on windows server 2012-2019, I want to create a ps script that cycles through a text file, in each line it stores the value as a variable that can be used in the batch file.
here is my code below; I just can't think of where to go after this;
$BF = gc "C:\Installs\FSRM_SCRIPTS\FILESCREEN_EXPORT\FSRM_Groups.txt"
$env:FSRM_Group
$FS = Foreach($BT in $BF){
Start-Process "cmd.exe" "/c C:\INSTALLS\FSRM_SCRIPTS\FILESCREEN_EXPORT\New_Exports\Batch_Import.bat"
}
$FS | out-file "C:\Installs\FSRM_SCRIPTS\FILESCREEN_EXPORT\New_Exports\Results\$env:COMPUTERNAME - Import.txt"
ok, so got it working as needed, but for reference, here is my code
$env:FSRM_Group
Foreach($BT in $BF){
$env:FSRM_Group = $BT
if($BT -match '([\w-?%s]+)'){
#Write-host "Valid"
$env:FSRM_Group2 = "Anti-Ransomware File Group"
}else{
#Write-host "Invalid"
$env:FSRM_Group2 = $BT
}
Start-Process "cmd.exe" "/c C:\INSTALLS\FSRM_SCRIPTS\FILESCREEN_EXPORT\New_Exports\Batch_Import.bat"
Write-output "$BT Installed Successfully" |out-file "C:\Installs\FSRM_SCRIPTS\FILESCREEN_EXPORT\New_Exports\Results\$env:COMPUTERNAME - Import.txt" -append
}```

What is this command doing? (PowerShell $?)

Anyone have any idea what this IF command is doing?
Connect-SPConfigurationDatabase -DatabaseName "$configDB" -Passphrase $secPhrase -DatabaseServer "$dbServer" -DatabaseCredentials $dbcreds -ErrorAction SilentlyContinue
If (-not $?)
{
Write-Host -ForegroundColor White " - No existing farm found.`n - Creating config database `"$configDB`"..." }
I'm speculating it's an alternative to :
Try { Do-Something -ea Stop }
Catch { Write-host $_ }
but it's just that, speculation.
I've never seen anything like this before and it's not showing up just the once in a script I'm inheriting. It's throwing me right off!
Thanks
$? is an automatic variable for the error status of the last executed command. See Get-Help about_Automatic_Variables.
Contains the execution status of the last operation. It contains TRUE if the last operation succeeded and FALSE if it failed.

Why aren't error thrown when I run this function as domain administrator?

This script is intended to recurse through a series of directories and when an error of type DirUnauthorizedAccessError,Microsoft or PowerShell.Commands.GetChildItemCommand is thrown it's supposed to call another function Take-Ownership which takes ownership of the directory and adds full permissions for the localAdmin and domain admin to the folder. (It's really a script used for easing the deletion of old user profiles):
function Test-Folder($FolderToTest, $localAdminName) {
# Remeber the old error preference...
$old_ErrorActionPreference = $ErrorActionPreference
$ErrorActionPreference = 'SilentlyContinue'
$error.Clear()
# Go through the directories...and capture errors in $error
Get-ChildItem $FolderToTest -Recurse -ErrorAction SilentlyContinue -ErrorVariable errz | Select FullName
Write-Host $errz.count
if ($errz.Count -eq 0) {
Write-Host "blah no errors"
foreach ($err in $errz) {
Write-Host "Error: $err"
if ($err.FullyQualifiedErrorId -eq "DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand") {
Write-Host Unable to access $err.TargetObject -Fore Red
Write-Host Attempting to take ownership of $err.TargetObject -Fore Yellow
Take-Ownership -Folder $err.TargetObject, -LocalAdminName $localAdminName
Test-Folder -FolderToTest $err.TargetObject -localAdminName $localAdminName
}
}
}
$ErrorActionPreference = $old_ErrorActionPreference
}
Unfortunately, it doesn't throw any errors when I run it as domain administrator. I've found a list of ErrorActionPreferences here, but the errors just seem to get ignored, and it outputs blah no errors What can I do to make sure I receive errors and that my Take-Ownership function is actually called?
Your code only enters the if block if $errz.Count is 0. With a count of 0 there are no elements in $errz, so there's nothing to do for the foreach loop.
Add an else branch to the conditional, move the foreach loop there, and the code should do what you want.
if ($errz.Count -eq 0) {
Write-Host "blah no errors"
} else {
foreach ($err in $errz) {
Write-Host "Error: $err"
...
}
}

Executing command doesn't result in script exception

We have a powershell script that deploys a database script. However, if the database script fails, the output doesn't throw exceptions to the powershell script.
Below is an example of the .ps1 file:
function Publish-DatabaseProject
{
sqlcmd -S . -b -v DatabaseName=Integration -q "alter table xx add test Varchar(10)"
}
function Add-Timestamp {
process {
if ($_.GetType() -eq [string]) {
"[$(Get-Date -Format o)] $_"
} else {
$_
}
}
}
function Write-LogFile {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)] [string] $Path,
[Parameter(Mandatory=$true, ValueFromPipeline=$true)] [object[]] $InputObject
)
begin {
$root = Split-Path -Path $Path -Parent
if ($root -and !(Test-Path -Path $root)) { New-Item -Path $root -Type Directory
| Out-Null }
}
process {
$InputObject |
Add-Timestamp |
Tee-Object -File $Path -Append
}
}
Publish-DatabaseProject -ErrorVariable DeployError 2>&1 |
Write-LogFile -Path "C:\output.log"
if ($DeployError -and $DeployError.Count -ne 0)
{
Write-Output "Failed"
} else
{
Write-Output "Succeeded"
}
The query in question is executing against a non-existent table. The text output shows:
[2015-12-11T14:42:45.1973944+00:00] Msg 4902, Level 16, State 1, Server ABDN-DEV-PC1, Line 1
[2015-12-11T14:42:45.2053944+00:00] Cannot find the object "xx" because it does not exist or you do not have permission
s.
Succeeded
I am expecting the last line to read: Failed.
If you run the sqlcmd line on its own, and follow it up with $LastExitCode, it does spit out a non-zero exit code.
> sqlcmd -S . -b -v DatabaseName=Integration -q "alter table xx add test Varchar(10)"
Msg 4902, Level 16, State 1, Server ABDN-DEV-PC1, Line 1
Cannot find the object "xx" because it does not exist or you do not have permissions.
> $LastExitCode
1
For various reasons, we cannot use Invoke-SqlCmd, and need to stick with SQLCMD.exe.
How can we make exceptions from within SQLCMD bubble out correctly to the calling script?
Your -ErrorVariable DeployError statement would only get triggered if the Publish-DatabaseProject cmdlet itself fails to execute. As that function is mostly a wrapper around sqlcmd.exe, there isn't any intelligence to bubble up this error. We can wrap it though by using the $LastExitCode automatic variable.
function Publish-DatabaseProject
{
sqlcmd -S . -b -v DatabaseName=Integration -q "alter table xx add test Varchar(10)"
if ($LastExitCode -ne 0)
{
Write-error $LastExitCode
throw $LastExitCode
}
}
Now, PowerShell will catch this error from the .exe, and you can use -ErrorVariable.
Update
So, since you want to keep running and not abandon ship when enountering an error, we need to wrap your Publish-DataBaseProject function with a try{}catch{} block, to catch the error we're generating, without stopping execution.
try {Publish-DatabaseProject -ErrorAction STOP -ErrorVariable DeployError 2>&1 |
Write-LogFile -Path "C:\output.log" }
catch{
Write-Output "Current job $($_), failed"
Write-Output "Exception $($Error.ExceptionID)"
}
Now we're properly generating an exception from a CMD, bubbling it up through our Function, and handling it as if it were a normal function, all using Native PowerShell. I believe this is what you were seeking to do. If not, post a gist of the whole script and I'll help you in a more targeted fashion.

How to find whether a certain file is available in the system path?

My Powershell script must be run from a VS command prompt, and I want to verity that by checking that msbuild.exe is in path. I managed to do it using where.exe:
where.exe msbuild.exe > $null
if ($LASTEXITCODE -ne 0)
{
throw "BuildAll must be run from ""Developer Command Prompt for VS2012"" shortcut."
}
However, this doesn't feel like "the Powershell way" - is there a Powershell-native way to do this?
Try this if the msbuild.exe must be in the same folder as the script is
if ( TEST-PATH (JOIN-PATH (Split-Path -parent $MyInvocation.MyCommand.Definition) "msbuild.exe " ))
{
...
}
else
{
...
}
If you want check if build.exe is available as command (any available path from $env:path) you can do:
if ([bool](Get-Command "msbuild.exe" -ea silentlycontinue))
{
...
}