I got this script off the technet website, but I get an error when I try to execute it on my Windows 7 machine. I am completely new to scripting, but I wonder if this was made for an older OS and needs a bit of changing for Windows 7? I'm quite sure the guy who wrote it up tested it.
I get the Windows Script Host Error as follows:
Line: 1
Char: 10
Error: Expected Identifier
Code: 800A03F2
Source: Microsoft VBScript compilation error.
Here's the script:
Function New-BackUpFolder($destinationFolder)
{
$dte = get-date
$dte = $dte.tostring() -replace "[:\s/]", "."
$backUpPath = "$destinationFolder" + $dte
$null = New-Item -path $backUpPath -itemType directory
New-Backup $dataFolder $backUpPath $backUpInterval
} #end New-BackUpFolder
Function New-Backup($dataFolder,$backUpPath,$backUpInterval)
{
"backing up $dataFolder... check $backUppath for your files"
Get-Childitem -path $dataFolder -recurse |
Where-Object { $_.LastWriteTime -ge (get-date).addDays(-$backUpInterval) } |
Foreach-Object { copy-item -path $_.FullName -destination $backUpPath -force }
} #end New-BackUp
# *** entry point to script ***
$backUpInterval = 1
$dataFolder = "C:\fso"
$destinationFolder = "C:\BU\"
New-BackupFolder $destinationFolder
that's actually Powershell and not VB script. You need to run the code inside Powershell for this to work.
This link looks pretty good for a brief introduction if you haven't done PS before.
http://www.abstrys.com/files/BeginningPowershellScripting.html
Related
I have written a script that works great on my machine (Windows 10) but I see an error when I run this code on other machine (Windows 7).
I need the script to check in c:\users\username\ directory for existence of tor.exe or directory called tor. The code for this part is this:
function FindTor() {
[int]$answer=0
$path = "C:\users\$env:username\"
$torEXE = Get-ChildItem -path $path -recurse -erroraction 'silentlycontinue' | Where-Object name -eq "Tor.exe"
$torDIR = Get-ChildItem -path $path -recurse -erroraction 'silentlycontinue' | Where-Object name -eq "tor"
if ($torEXE.Exists -or $torDIR.Exists) {$answer = 1}
Return $answer
}
On my computer - no problem. On the machine with windows 7 I get this:
I have Windows Server 2016 Datacenter (64 bit) as a File Server (contains several Shared folder & subfolders).
I want to make a list OR export user Folder Structure along with permissions ( Read, Modify, Full .. etc..)
I tried with below PS script but I am getting an error message with I have mentioned after the script.
Powershell
$FolderPath = dir -Directory -Path "E:\Project Folders\#Folder_Name" -Recurse -Force
$Report = #()
Foreach ($Folder in $FolderPath) {
$Acl = Get-Acl -Path $Folder.FullName
foreach ($Access in $acl.Access)
{
$Properties = [ordered]#{'FolderName'=$Folder.FullName;'AD Group or User'=$Access.IdentityReference;'Permissions'=$Access.FileSystemRights;'Inherited'=$Access.IsInherited}
$Report += New-Object -TypeName PSObject -Property $Properties
}
}
$Report | Export-Csv -path "C:\Folder Permissions\Folder Name.csv"
Error:
dir : Access to the path 'E:\Project Folders**Folder Path**\New folder' is denied. At C:\Users\Administrator\Documents\PS Script**File Name**.ps1:1 char:15 + ... olderPath = dir -Directory -Path "E:\Project Folders**Folder Name**" -Re ...+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (E:\Project Fold...ngar\New folder:String) [Get-Child Item], UnauthorizedAccessException + FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
Please help me out!
Thanks in Advance
As noted by the other comments.
This is not a PowerShell error/issue, it is a permissions one. The same thing can/will happen if you say you did this use case on the Windows folder tree.
Since you know this will happen, either fix the permissions on the tree you are working on or do this.
Get-ChildItem -Directory -Path 'C:\Windows\System32' -Recurse -ErrorAction SilentlyContinue
or if you want to just stop when a path fails.
# Treat non-terminating erros as terminating
$RootFolderUnc = 'C:\Windows\System32'
Try {Get-ChildItem -Directory -Path $RootFolderUnc -Recurse -ErrorAction Stop}
Catch [System.UnauthorizedAccessException]
{
Write-Warning -Message "$env:USERNAME. You do not have permissions to view this path."
$_.Exception.Message
}
Update2:
Now, when I know, that x32 is the problem I debugged into the script using powershell_ise_x32 and found out, that $Word.Documents is null.
So Powershell-API for Word has a different behaviour in x32 PowerShell, then in 64bit.
Update:
The error occurs, when using PowerShell x32 and occurs NOT on PowerShell 64bit. That was really it. Powershell x32 was executed because I started it from the Total Commander 32bit.
The question is now - why 32bit and 64bit PowerShell have different behaviour?
Initial Question:
I wrote a powershell script, to convert my WordDocuments and merge them to one.
I wrote a Batch script, to start this powershell script.
When I execute the script directly in "Powershell ISE" the script works fine.
When I execute the batch script as Administrator via context menu, the script reports errors. In this case the C:\WINDOWS\SysWOW64\cmd.exe is executed.
When I execute another cmd.exe found on my system as Administrator - everything works fine:
"C:\Windows\WinSxS\amd64_microsoft-windows-commandprompt_31bf3856ad364e35_10.0.15063.0_none_9c209ff6532b42d7\cmd.exe"
Why do I have different behaviour in different cmd.exe? What are those different cmd.exe?
Batch Script:
cd /d "%~dp0"
powershell.exe -noprofile -executionpolicy bypass -file "%~dp0%DocxToPdf.ps1"
pause
Powershell Script
$FilePath = $PSScriptRoot
$Pdfsam = "D:\Programme\PDFsam\bin\run-console.bat"
$Files = Get-ChildItem "$FilePath\*.docx"
$Word = New-Object -ComObject Word.Application
if(-not $?){
throw "Failed to open Word"
}
# Convert all docx files to pdf
Foreach ($File in $Files) {
Write-Host "Word Object: " $Word
Write-Host "File Object: " $Word $File
Write-Host "FullName prop:" $File.FullName
# open a Word document, filename from the directory
$Doc = $Word.Documents.Open($File.FullName)
# Swap out DOCX with PDF in the Filename
$Name=($Doc.FullName).Replace("docx","pdf")
# Save this File as a PDF in Word 2010/2013
$Doc.SaveAs([ref] $Name, [ref] 17)
$Doc.Close()
}
# check errors
if(-not $?){
Write-Host("Stop because an error occurred")
pause
exit 0
}
# wait until the conversion is done
Start-Sleep -s 15
# Now concat all pdfs to one single pdf
$Files = Get-ChildItem "$FilePath\*.pdf" | Sort-Object
Write-Host $Files.Count
if ($Files.Count -gt 0) {
$command = ""
Foreach ($File in $Files) {
$command += " -f "
$command += "`"" + $File.FullName + "`""
}
$command += " -o `"$FilePath\Letter of application.pdf`" -overwrite concat"
$command = $Pdfsam + $command
echo $command
$path = Split-Path -Path $Pdfsam -Parent
cd $path
cmd /c $command
}else{
Write-Host "No PDFs found for concatenation"
}
Write-Host -NoNewLine "Press any key to continue...";
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown");
I've found $PSScriptRoot to be unreliable.
$FilePath = $PSScriptRoot;
$CurLocation = Get-Location;
$ScriptLocation = Split-Path $MyInvocation.MyCommand.Path
Write-Host "FilePath = [$FilePath]";
Write-Host "CurLocation = [$CurLocation]";
Write-Host "ScriptLocation = [$ScriptLocation]";
Results:
O:\Data>powershell ..\Script\t.ps1
FilePath = []
CurLocation = [O:\Data]
ScriptLocation = [O:\Script]
As to the differences between the various cmd.exe implementations, I can't really answer that. I should have thought they'd be functionally identical, but maybe there's 32/64-bit differences that matter.
The error occurs, when using PowerShell x32 and occurs NOT on PowerShell 64bit.
I debugged into the script using powershell_ise_x32 and found out, that $Word.Documents is null.
This is because on my system Word 64bit is installed.
I am trying to write a powershell script that does the following:
Check to see if a folder on a remote machine(text list of computers) exists, if so delete it.
Copy a folder from a remote share to the same machine and if there is an error output to an error log file, if not, output to a success log file.
I have searched but have been unable to find a solution to my seemingly simple problem, please see my code below:
$computers=Get-Content C:\pcs.txt
$source="\\RemoteShare\RemoteFolder"
$dest="C$\Program Files\Destination"
foreach ($computer in $computers) {
If (Test-Path \\$computer\$dest){
Remove-Item \\$computer\$dest -Force -Recurse
}
Copy-Item $source \\$computer\$dest -recurse -force -erroraction silentlycontinue
If (!$error)
{Write-Output $computer | out-file -append -filepath "C:\logs\success.log"}
Else
{Write-Output $computer | out-file -append -filepath "C:\logs\failed.log"}
}
Currently, when the script runs, everything is getting put in the failed.log file, regardless of if it fails or not.
How can I properly handle errors in powershell, while running through a for loop?
Here's an example.
$array = #(3,0,1,2)
foreach ($item in $array)
{
try
{
1/$item | Out-Null
$computer | Add-Content -Path "C:\logs\success.log"
}
catch
{
"Error: $_" | Add-Content -Path "C:\logs\failed.log"
}
}
Don't use $error, it always contains an array of recent error objects, even if the last command was successful. To check the results of the last command, use the $?, it will be false if the last command failed.
See about_Automatic_Variables for more details on these variables.
I am using a batch script for getting the latest version of specific projects. This script only runs tf.exe and gets the latest version of some Binaries. Everything works fine, but I would like to change the attrib of the downloaded files to be writeable (by deafult these files are read-only). For that I want to determine the local path of the files and use the attrib-command from batch.
tf.exe workfold [Workspace] shows me the local path in some kind of listing but it would be easier, if it only shows me what I want so I can use the prompt. Until now the it looks like this:
tf.exe workfold [Workspace]
=======================================
Arbeitsbereich: XYZ-xxxxxx (Username)
Auflistung: TFS-URL
[Workspace]: C:\xxx\TFS\xxx
Is it possible to determine only the local path mapping of a TFS Workspace so that I can use the prompt for the attrib-command without parsing?
What about the following (crude!!!) concept?
function Get-TfsWorkfold([string]$TfsCollection, [string]$TfsWorkspace)
{
$TfExePath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio 10.0\Common7\IDE\TF.exe"
Write-Output "Getting workfold for '$TfsCollection'->'$TfsWorkspace'..."
Push-Location $LocalPath
& "$TfExePath" workfold /collection:$TfsCollection /workspace:$TfsWorkspace
}
function Handle-Path()
{
param([Parameter(ValueFromPipeline=$true,Position=0)] [string] $line)
$startIndex = $line.IndexOf(': ') + 2;
$correctedLine = $line.subString($startIndex, $line.length - $startIndex - 1);
Write-Output $correctedLine;
Get-ChildItem $correctedLine
}
Get-TfsWorkfold "{serverAndcollection}" "{workspace}" > c:\temp\test.txt
Select-String c:\temp\test.txt -pattern:': ' | Select-Object Line | Handle-Path
The last line in Handle-Path is the example which you can rewirte with whatever you want to. It is PowerShell but it should work as you want.
Replace {serverAndcollection} and {workspace}.
Real men do it in one line
powershell -command "& {tf workfold | Select-String -pattern:' $' -SimpleMatch | Select-Object Line | ForEach-Object {$startIndex = $_.Line.IndexOf(': ') + 2; $_.Line.subString($startIndex, $_.Line.length - $startIndex - 1)}}"
Current answer will only return one last path if there are many.
You can also do it without any string manipulation, with calls to TF.exe. I have wrapped that in PowerShell scripts, so you get the following:
function Add-TfsTypes
{
# NOTE: Not all of the below are needed, but these are all the assemblies we load at the moment. Please note that especially NewtonSoft dll MUST be loaded first!
$PathToAssemblies = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer"
Add-Type -Path "$PathToAssemblies\NewtonSoft.Json.dll"
Add-Type -Path "$PathToAssemblies\System.Net.http.formatting.dll"
Add-Type -Path "$PathToAssemblies\Microsoft.TeamFoundation.Client.dll"
Add-Type -Path "$PathToAssemblies\Microsoft.TeamFoundation.Common.dll"
Add-Type -Path "$PathToAssemblies\Microsoft.TeamFoundation.VersionControl.Client.dll"
Add-Type -Path "$PathToAssemblies\Microsoft.TeamFoundation.WorkItemTracking.Client.dll"
}
function Get-TfsServerPathFromLocalPath {
param(
[parameter(Mandatory=$true)][string]$LocalPath,
[switch]$LoadTfsTypes
)
if ($LoadTfsTypes) {
Add-TfsTypes # Loads dlls
}
$workspaceInfo = [Microsoft.TeamFoundation.VersionControl.Client.Workstation]::Current.GetLocalWorkspaceInfo($LocalPath)
$server = New-Object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection $workspaceInfo.ServerUri
$workspace = $workspaceInfo.GetWorkspace($server)
return $workspace.GetServerItemForLocalItem($LocalPath)
}
The above method can then be called like this:
$serverFolderPath = Get-TfsServerPathFromLocalPath $folderPath -LoadTfsTypes
$anotherServerPath = Get-TfsServerPathFromLocalPath $anotherItemToTestPathOn