File is auto created, the script should auto rename and move it, but they don't move - powershell-2.0

long time listener, first time caller,
I have a need to create a Powershell script (ver 2 or lower) that:
-continually monitors one specific directory for new/changed files
-logs the file that was created with a date/time stamp in a log file that's:
--created on a daily basis with the name of "log Date/Time.txt"
-renames the file, appending the date/time
-logs that it renamed it
-maps a drive with a specific username/password combo
-moves it from dirA to dirB (the mapped drive is dirB)
-logs that it moved it
-unmaps the drive
-if for whatever reason it stopped running and we start it back up, it'll rename, maps the drive, move, unmap the drive, and log all files in dirA to dirB
In it's current form, I've stripped the Mapping of the dir out to troubleshoot it moving the file on a local drive just to keep from troubleshooting a network drive.
I've been staring at this for over a week and am tired of hitting my head against the desk. Can someone PLEASE put me out of my misery and let me know what I've done wrong?
THANK YOU in advance!
I've honestly tried SO many combos, different routines, I don't even know what to put here.
In the box below, I've put the main part of the script that isn't working correctly It renames the files as they come in, but doesn't move them.
$rename = $_.Name.Split(".")[0] + "_" + ($_.CreationTime | Get-Date -Format MM.dd.yyy) + "_" + ($_.CreationTime | Get-Date -Format hh.mm.ss) + ".log"
Write-Output "File: '$name' exists at: $source - renaming existing file first" >> $scriptlog
Rename-Item $_ -NewName $rename
Wait-Event -Timeout 3
Move-Item "$_($_.Directory)$name" -destination $destination
Write-Output "File: '$name' moved to $destination on $date" >> $scriptlog
Whole code available below:
#Log Rename/Move script
$userName = "copyuser"
$newpass = Read-Host -Prompt 'Type the new Password'
$password = ConvertTo-SecureString -String $newpass -AsPlainText -Force
$PathToMonitor = "C:\Users\Administrator\Desktop\FolderA"
$destination = "C:\Users\Administrator\Desktop\FolderB"
$scriptlog = "C:\Users\Administrator\Desktop\ScriptLogs\" + [datetime]::Today.ToString('MM-dd-yyy') + "_TransferLog.txt"
$FileSystemWatcher = New-Object System.IO.FileSystemWatcher
$FileSystemWatcher.Path = $PathToMonitor
$FileSystemWatcher.IncludeSubdirectories = $false
$FileSystemWatcher.EnableRaisingEvents = $true
$dateTime = [datetime]::Today.ToString('MM-dd-yyy') + " " + [datetime]::Now.ToString('HH:mm:ss')
Write-Output "*******************************************************************************************" >> $scriptLog
Write-Output "*********************Starting Log Move Script $dateTime**********************" >> $scriptLog
Write-Output "*******************************************************************************************" >> $scriptLog
$Action = {
$details = $event.SourceEventArgs
$Name = $details.Name
$FullPath = $details.FullPath
$OldFullPath = $details.OldFullPath
$OldName = $details.OldName
$ChangeType = $details.ChangeType
$Timestamp = $event.TimeGenerated
$text = "{0} was {1} at {2}" -f $FullPath, $ChangeType, $Timestamp
Write-Output "" >> $scriptlog
Write-Output $text >> $scriptlog
switch ($ChangeType)
{
'Changed' { "CHANGE"
Get-ChildItem -path $FullPath -Include *.log | % {
$rename = $_.Name.Split(".")[0] + "_" + ($_.CreationTime | Get-Date -Format MM.dd.yyy) + "_" + ($_.CreationTime | Get-Date -Format hh.mm.ss) + ".log"
Write-Output "File: '$name' exists at: $source - renaming existing file first" >> $scriptlog
Rename-Item $_ -NewName $rename
Wait-Event -Timeout 3
Move-Item "$_($_.Directory)$name" -destination $destination
Write-Output "File: '$name' moved to $destination on $date" >> $scriptlog
}
}
'Created' { "CREATED"
Get-ChildItem -path $FullPath -Include *.log | % {
$rename = $_.Name.Split(".")[0] + "_" + ($_.CreationTime | Get-Date -Format MM.dd.yyy) + "_" + ($_.CreationTime | Get-Date -Format hh.mm.ss) + ".log"
Write-Output "File: '$name' exists at: $source - renaming existing file first" >> $scriptlog
Rename-Item $_ -NewName $rename
Wait-Event -Timeout 3
Move-Item "$($_.Directory)$rename" -Destination $destination
Write-Output "File: '$name' moved to $destination on $date" >> $scriptlog
}
}
'Deleted' { "DELETED"
}
'Renamed' {
}
default { Write-Output $_ >> $scriptlog}
}
}
$handlers = . {
Register-ObjectEvent -InputObject $FileSystemWatcher -EventName Changed -Action $Action -SourceIdentifier FSChange
Register-ObjectEvent -InputObject $FileSystemWatcher -EventName Created -Action $Action -SourceIdentifier FSCreate
}
Write-Output "Watching for changes to $PathToMonitor" >> $scriptlog
try
{
do
{
Wait-Event -Timeout 1
Write-host "." -NoNewline
} while ($true)
}
finally
{
# EndScript
Unregister-Event -SourceIdentifier FSChange
Unregister-Event -SourceIdentifier FSCreate
$handlers | Remove-Job
$FileSystemWatcher.EnableRaisingEvents = $false
$FileSystemWatcher.Dispose()
write-output "Event Handler disabled." >> $scriptlog
}

Well, I found my issue. A dumb issue if I look at it and think about it. It was how I was calling the current directory containing the file(s) to move after being renamed.
Move-Item "$_($_.Directory)$name" -destination $destination
The issue in the above code is the "$($.Directory). It needs to be:
Move-Item -path $PathToMonitor$name -destination $destination
Other things may work, and may be better, but at least that fixes the moving after naming issue I was having.
Now onto adding the Mapping Drive and other stuff that's needed to fully finish what I need.
If I think about it, I'll post my entire code when done for anyone else it can help in the future.

Related

Error in Upload watchdog: [System.Object[]] no method with the name "op_Addition"

I need help with a script that monitors the upload.
The script is intended to prevent crashes of OBS, where OBS simply stops sending data. I have already run this script on several streaming PCs - without problems. But on a new streaming PC it just won't run.
Here is the script for now:
$threshold = 6000
$timer = new-timespan -Seconds 10
$wmi = 0
$count = 0
$clock = [diagnostics.stopwatch]::StartNew()
while ($clock.elapsed -lt $timer){
$wmi += (Get-WMIObject -Class Win32_PerfFormattedData_Tcpip_NetworkInterface | Select-Object BytesSentPerSec).BytesSentPerSec
$count++
}
$kbytes = ($wmi/$count) / 1kb * 8 #to kbit/s
if($kbytes -le $threshold)
{
Write-Output $kbytes
Write-Host "Neustart"
taskkill /f /im obs64.exe
timeout /t 5
Start-Process -FilePath "obs64.exe" -WorkingDirectory "C:\Program Files\obs-studio\bin\64bit\" --startstreaming
}
else
{
Write-Output $kbytes
Write-Host "Alles OK"
}
As an error I get this:
Code:
Error when calling the method. [System.Object[]] no method with the name "op_Addition".
In C:\Users\stream1\Desktop\watchdog.ps1:8 Zeichen:5
+ $wmi += (Get-WMIObject -Class Win32_PerfFormattedData_Tcpip_Netwo ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (op_Addition:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
The program was written for me by someone. Unfortunately, I myself have no experience in programming in Powershell. I would be very grateful for any help.
I hope someone can help me.
Thanks a lot
Greeting
Thomas
"$wmi = 0" --> "$wmi = #()"
Error:
Error calling the method because [System.Object[]] does not contain a method named "op_Division".
In C:\Users\stream1\Desktop\watchdog.ps1:12 character:1
+ $kbytes = ($wmi/$count) / 1kb * 8 #to kbit/s
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (op_Division:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound

file not found,jenkins pipline

I am getting file not found error on my Jenkins job.
if (component_meta ==null)
echo "path = " + component_meta
else if (component_meta.tf_version !=null){
echo "path = " + component_meta
echo "version = " + component_meta.tf_version
dir ("base/" + component_meta.path){
sh 'rm -rf .terra*'
sh "terragrunt plan --terragrunt-tfpath /usr/local/bin/tf/versions/" + component_meta.tf_version + "/terraform" + " -detailed-exitcode"
}
}
error I beleive is in the system of below command
sh "terragrunt plan --terragrunt-tfpath /usr/local/bin/tf/versions/" + component_meta.tf_version + "/terraform" + " -detailed-exitcode"

Advance installer create registry using command line

I have gone through the following link http://www.advancedinstaller.com/user-guide/new-reg.html to create registries using command line
$InstallerName = "Installer1.2.10"
$registryParams ="/edit $aippath /NewReg -RegKey HKLM\Software\MYApplication\Database\*"
$SourceDir = "D:\AdvanceInstaller"
$AdvanceInstallerPath = Get-ChildItem "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | ForEach-Object {Get-ItemProperty $_.PSPath} | Where-Object {$_.DisplayName -match "Advanced Installer"}
$InstallerPath= "$($AdvanceInstallerPath.InstallLocation)bin\x86\AdvancedInstaller.com"
$aippath = "$SourceDir\$($InstallerName).aip"
$ProductName = "MYApplication"
$DeleteReg = "/edit $aippath /DelReg -RegKey HKLM\SOFTWARE\WOW6432Node\MyApplication"
$ProductParams = "/edit $aippath /SetProperty ProductName=$ProductName"
$repository = "/edit $aippath /SetAppdir -buildname DefaultBuild -path C:\MyApplication"
$newParameters = "/newproject $aippath -type enterprise"
$buildParams = "/build $aippath"
Start-Process -FilePath $InstallerPath -ArgumentList $newParameters -Wait -WindowStyle Hidden -ErrorAction Stop
Start-Process -FilePath $InstallerPath -ArgumentList $ProductParams -Wait -WindowStyle Hidden -ErrorAction Stop
Start-Process -FilePath $InstallerPath -ArgumentList $repository -Wait -WindowStyle Hidden -ErrorAction Stop
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "$InstallerPath"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "$DeleteReg"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()
$stderr = $p.StandardError.ReadToEnd()
Write-Host $stdout
Write-Host $stderr
Start-Process -FilePath $InstallerPath -ArgumentList $buildParams -Wait -WindowStyle Hidden -ErrorAction Stop
Start-Process -FilePath $InstallerPath -ArgumentList $registryParams -Wait -WindowStyle Hidden -ErrorAction Stop
But I am unable to see the desired registry created after installation. What I need is as per the following after installing the software
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\MySoftware]
"Path"="C:\MySoftware"
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\MySoftware\Database]
"connectionstring"="server=.;initial db=master"
Also when installing the msi the default registry is getting created as My Company\Project which I don't want
After lot of trail and error here is the final code
$InstallerName = "Installer1.2.10"
$SourceDir = "D:\AdvanceInstaller"
$AdvanceInstallerPath = Get-ChildItem "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | ForEach-Object {Get-ItemProperty $_.PSPath} | Where-Object {$_.DisplayName -match "Advanced Installer"}
$InstallerPath= "$($AdvanceInstallerPath.InstallLocation)bin\x86\AdvancedInstaller.com"
$aippath = "$SourceDir\$($InstallerName).aip"
$ProductName = "MyApplication"
$DeleteReg = "/edit $aippath /DelReg -regkey HKUD\Software\[Manufacturer]"
Start-Process -FilePath $InstallerPath -ArgumentList $DeleteReg -Wait -WindowStyle Hidden -ErrorAction Stop
$registryParams = "/edit $aippath /NewReg -RegKey HKUD\Software\MyApplication -data ''"
$registryParams1 = "/edit $aippath /NewReg -RegValue HKUD\Software\MyApplication\path -data C:\MyApplication"
Start-Process -FilePath $InstallerPath -ArgumentList $registryParams -Wait -WindowStyle Hidden -ErrorAction Stop
Start-Process -FilePath $InstallerPath -ArgumentList $registryParams1 -Wait -WindowStyle Hidden -ErrorAction Stop

Parse Command Outputting Horizontally

I have a script that parses a log file for the last 15 lines but it outputs the data in a horizontal line which I think interferes when I try to get an average of the numbers in the file.
Here's an example of the log file I'm parsing:
3/22/2016 9:11:21 AM 44.0
3/22/2016 9:11:22 AM 44.1
3/22/2016 9:11:23 AM 44.2
3/22/2016 9:11:24 AM 44.3
And here's my PowerShell command that parses the last 15 lines of the active log file.
$regexNUM = '\d+\.\d+'
$NUMLog = Get-ChildItem -Path 'C:\Users\Admin\Documents' |
Where-Object {$_.Name -match "LOGFILE"} |
Sort LastWriteTime | Select -Last 1
$NUMBERS = Get-Content -Path "C:\Users\Admin\Documents\$NumLog" -Tail 15 |
Select-String -Pattern $regexNum -AllMatches |
% { $_.Matches } | % { $_.Groups }
When I do a Write-Host $NUMBERS it outputs the data like this:
39.5 39.6 39.7 39.8 39.9 40.0 40.1 40.2 40.3 40.4 40.5 40.6 40.7 40.8 40.9
And here's how I'm trying to get the average of these 15 numbers:
$Average = $NUMBERS | Measure-Object -Average | Select Average
When I do Write-Host $Average it says:
Measure-Object : Input object "39.5" is not numeric.
At C:\Users\Admin\Documents\SampleTest.ps1:26 char:30
+ $Average = $NUMBERS | Measure-Object -Average | Select Average
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidType: (39.5:Match) [Measure-Object], PSInvalidOperationException
+ FullyQualifiedErrorId : NonNumericInputObject,Microsoft.PowerShell.Commands.MeasureObjectCommand
I'm not sure why it would say the number 39.5 is not numeric but all I can assume is that it doesn't like it being horizontal with the spaces maybe. It throws one of those errors for each of the 15 numbers too.
Problem:
The problem in your code is that you are actually feeding objects of type System.Text.RegularExpressions.Match to the Measure-Object cmdlet, and not numbers.
The Write-Host command is automatically converting the Match object to text when it needs to output it to the console, and that makes you think it looks like numbers.
Solution:
To fix that, change the following line to get values inside the Match objects:
$NUMBERS = Get-Content -Path "C:\Users\Admin\Documents\$NumLog" -Tail 15 |
Select-String -Pattern $regexNum -AllMatches |
% { $_.Matches } | % { $_.Value }
Advice:
To fix problems like this yourself, you can use the the Get-Member cmdlet to check what is the type returned.
In your case, you can send the output of the second Get-Content cmdlet to Get-Member, instead of saving it to a variable:
Get-Content -Path "C:\Users\Admin\Documents\$NumLog" -Tail 15 |
Select-String -Pattern $regexNum -AllMatches |
% { $_.Matches } | % { $_.Groups } | Get-Member

Backup SSRS Encryption Keys Using Powershell

I have made the following script from google for backing up the SSRS Encryption keys:
cls
$pwd = "sa#123#123"
$SSRSClass = Get-Wmiobject -namespace "root\microsoft\sqlserver\reportserver\rs_BPSSRS\v10\admin" -class "MSReportServer_ConfigurationSetting"
$key = $SSRSClass.BackupEncryptionKey($pwd)
$stream = [System.IO.File]::Create("c:\\SSRS.snk", $key.KeyFile.Length)
$stream.Write($key.KeyFile, 0, $key.KeyFile.Length)
$stream.Close()
But I'm getting the following errors:
Method invocation failed because [System.Object[]] doesn't contain a method named 'BackupEn
cryptionKey'.
At line:5 char:38
+ $key = $SSRSClass.BackupEncryptionKey <<<< ($results)
+ CategoryInfo : InvalidOperation: (BackupEncryptionKey:String) [], RuntimeEx
ception
+ FullyQualifiedErrorId : MethodNotFound
Exception calling "Create" with "2" argument(s): "Positive number required.
Parameter name: bufferSize"
At line:6 char:35
+ $stream = [System.IO.File]::Create <<<< ("c:\\SSRS.snk", $key.KeyFile.Length)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
You cannot call a method on a null-valued expression.
At line:7 char:14
+ $stream.Write <<<< ($key.KeyFile, 0, $key.KeyFile.Length)
+ CategoryInfo : InvalidOperation: (Write:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At line:8 char:14
+ $stream.Close <<<< ()
+ CategoryInfo : InvalidOperation: (Close:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
I'm using powershell v2. I tried finding about this but no luck. There are around 50+ SSRS servers in our environment and doing backup manually is tiresome. Hence, we came up with this automation. Kindly provide your comments.
Thanks
This piece of code should do the trick:
$ComputerName = "."
$KeyFolder = "C:\Temp"
$KeyPassword = "sa#123#123"
$TimeStamp = Get-Date -Format "-yyyyMMdd-HHmmss"
Get-WmiObject -Namespace "Root\Microsoft\SqlServer\ReportServer" -Class "__Namespace" -ComputerName $ComputerName |
Select-Object -ExpandProperty Name |
% {
$NameSpaceRS = $_
$InstanceName = $NameSpaceRS.SubString(3)
$KeyFileName = Join-Path -Path $KeyFolder -ChildPath ($InstanceName + $Timestamp + ".snk")
"Found Reporting Services in instance '$($InstanceName)' on $($ComputerName); will save key to '$($KeyFileName)' ..."
$SQLVersion = (Get-WmiObject -Namespace "Root\Microsoft\SqlServer\ReportServer\$($NameSpaceRS)" -Class "__Namespace" -ComputerName $ComputerName).Name
$SSRSClass = Get-WmiObject -Namespace "Root\Microsoft\SqlServer\ReportServer\$($NameSpaceRS)\$($SQLVersion)\Admin" -Query "SELECT * FROM MSReportServer_ConfigurationSetting WHERE InstanceName='$($InstanceName)'" -ComputerName $ComputerName
$Key = $SSRSClass.BackupEncryptionKey($KeyPassword)
If ($Key.HRESULT -ne 0) {
$Key.ExtendedErrors -join "`r`n" | Write-Error
} Else {
$Stream = [System.IO.File]::Create($KeyFileName, $Key.KeyFile.Length)
$Stream.Write($Key.KeyFile, 0, $Key.KeyFile.Length)
$Stream.Close()
}
}
The errors that you have mentioned are because your code is trying to fetch information from duplicate entries. Meaning, if you try the above code on the server where only one named instance of SSRS is running, then I suppose it will succeed. Just try this piece and give your comments.
CHEERS.

Resources