I don't know what I'm doing wrong, I can't delete files, I'm working with a console application, the method SPFile.Delete() does nothing.
Here is some code:
for (int ii = web.Folders[url + documentsfolder].ItemCount - 1; ii >= 0; ii--)
{
SPFile file = web.GetFile(web.Folders[url + documentsfolder].Files[ii].UniqueId);
if (file.Exists)
{
file.Delete();
}
}
It doesn't throw an exception. It just stops in the first file, I don't know why.
Hope you can help
Hi Here is the code snippet for Deleting folders or files of shared Documents. This might give you clue for using proper command DeleteItemById for deletion.
$web = Get-SPWeb -Identity "http://sharepoint2010/myweb/"
$list = $web.GetList("http://sharepoint2010/myweb/Shared%20Documents/")
function ProcessFolder {
param($folderUrl)
$folder = $web.GetFolder($folderUrl)
foreach ($file in $folder.Files) {
#Delete file by deleting parent SPListItem
$list.Items.DeleteItemById($file.Item.Id)
}
}
#Collect files to delete
ProcessFolder($list.RootFolder.Url)
#Download files in folders
foreach ($folder in $list.Folders) {
ProcessFolder($folder.Url)
}
#Delete folders
foreach ($folder in $list.Folders) {
try {
$list.Folders.DeleteItemById($folder.ID)
}
catch {
#Deletion of parent folder already deleted this folder
#I really hate this
}
}
Related
i have got the drag and drop working on my Windows Form. i can drop items from my desktop or any folder but if i try to Drag an attachment straight from Outlook it won't do any thing. do i need to add extra PowerShell commands int my current code
######################################## This is For Drag And Drop
$listBox1_DragOver = [System.Windows.Forms.DragEventHandler]{
if ($_.Data.GetDataPresent([Windows.Forms.DataFormats]::FileDrop))
{
$_.Effect = 'Copy'
}
Else
{
$_.Effect = 'None'
}
}
$listBox1_DragDrop = [System.Windows.Forms.DragEventHandler]{
foreach ($filename in $_.Data.GetData([Windows.Forms.DataFormats]::FileDrop))
{
$listBox1.Items.Add($filename)
}
}
### Add events to form ###
$listBox1.Add_DragOver($listBox1_DragOver)
$listBox1.Add_DragDrop($listBox1_DragDrop)
#$form.Add_FormClosed($form_FormClosed)
#### Show form and return result ###
$dialogResult = $Form12.ShowDialog()
if ($dialogResult -eq [System.Windows.Forms.DialogResult]::OK)
{
$Form12.SuspendLayout()
[array]$items = $listbox1.Items| sort -CaseSensitive
if ($items.Count -gt 1){
$items
}
ELSE
{
[string]$items[0]
}
$Form12.Close() | out-null
}
After lot's of research i came across the code below, to summarise what it does.
it will let you drag and drop files out of Outlook, it will then copy and paste that into a folder which then gives you the path and file name. it is pretty cool so if anyone else is stuck here is my working script and how i implemented it to my form
######################################## This is For Drag And Drop
$Listbox1.AllowDrop = $true
$Listbox1.Add_DragDrop({
if ($_.Data.GetDataPresent([Windows.Forms.DataFormats]::FileDrop)) {
foreach ($FileName in $_.Data.GetData([Windows.Forms.DataFormats]::FileDrop)) {
Copy-Item -Path $FileName -Destination $textbox6.text -Force
$Listbox1.Items.Add($FileName)
}
}
else
{
$Outlook = New-Object -ComObject Outlook.Application;
$Selection = $Outlook.ActiveExplorer().Selection
foreach ($Item in $Selection) {
foreach ($Attachment in $Item.Attachments) {
Write-Verbose $Attachment.FileName
$Name = Join-Path -Path $textbox6.text-ChildPath $Attachment.FileName
$Attachment.SaveAsFile($Name)
}
}
}
})
$Listbox1.Add_DragEnter({$_.Effect = [Windows.Forms.DragDropEffects]::Copy})
$Form12.Controls.Add($Listbox1)
# Activate the form
[void] $Form12.ShowDialog()
i had to change my form a little by adding an Input Folder Button & Textbox6 to show the text of the folder that has been selected this is important as the Script above needs a directory to save the files to, please see code below.
###################################### Get Folder Using Folder Browser and output text into textbox
$button4_Click = {
$folderBrowserDialog3=New-Object System.Windows.Forms.FolderBrowserDialog
[void]$folderBrowserDialog3.ShowDialog()
$folderBrowserDialog3.SelectedPath
$textBox6.Text = $folderBrowserDialog3.SelectedPath
}
$button6_Click = {
$folderBrowserDialog1=New-Object System.Windows.Forms.FolderBrowserDialog
[void]$folderBrowserDialog1.ShowDialog()
$folderBrowserDialog1.SelectedPath
$textBox2.Text = $folderBrowserDialog1.SelectedPath
}
$button7_Click = {
$folderBrowserDialog2=New-Object System.Windows.Forms.FolderBrowserDialog
[void]$folderBrowserDialog2.ShowDialog()
$folderBrowserDialog2.SelectedPath
$textBox3.Text = $folderBrowserDialog2.SelectedPath
}
after i got that to work the thing that bugged me the most was i couldn't see the files in the listbox so i added a button to do exactly that please see code below
###################################### Shows Files In ListBox 1
$button5_Click = {
#$textbox8.Text = ""
$listBox1.Items.Clear()
$items = Get-ChildItem $textbox6.Text
ForEach($item in $items){
$listBox1.Items.Add($item.FullName)
}
}
as you can see i have added $listbox1.Items.Clear() this will enable you to keep clicking the show files button without it duplicating the path and file in the listbox
the final result of my Form has come out great please see my image layout below, if anyone needs help to get it working on your own Form please comment and i will do my best to help.
I am running the following Powershell Script against a list of SQL Instances to return Instance information, including users and roles. I want to use Powershell to do this as I'm collating the data and will import into another system which will do some analysis.
I created the following script which creates an XML file output for each instance found. The script works great (yes, it's probably clunky and an awful way to do this, but I'm learning so please feel free to give me a shove in the right direction), however for one of the servers with a few hundred SQL logins I get an overflow message appear on screen, the XML file is not closed correctly and as a result I can't import the results into my analysis system.
I would like either:
Ideas on what could be causing the overflow. For reference, the output XML that crashes out is 2.5MB in size, with approx 39,000 lines in the XML output before the overflow occurs
[OR]
Another way to get this output - CSV is an option but I don't know enough how to output this - can anyone provide tips?
Thank you in advance
#Input file is a plain text file with the name of each of the instances listed in it
$InputFile="C:\Tasks\SQL\Permissions\in\Instances.txt"
$OutputFolder="\\networkdrive\sharedfolder\"
Function GetDBUserInfo($Dbase)
{
if ($dbase.status -eq "Normal") # ensures the DB is online before checking
{$users = $Dbase.users | where {$_.login -eq $SQLLogin.name} # Ignore the account running this as it is assumed to be an admin account on all servers
foreach ($u in $users)
{
if ($u)
{
$XmlWriter.WriteStartElement("Login")
$XmlWriter.WriteElementString('DBName', $dbase.name)
$XmlWriter.WriteElementString('LoginName', $SQLLogin.name)
$XmlWriter.WriteStartElement('Login_Roles')
$DBRoles = $u.enumroles()
foreach ($role in $DBRoles)
{
$XmlWriter.WriteElementString('Role', $Dbase.name)
}
$XmlWriter.WriteEndElement()#Login_Roles
#Get any explicitly granted permissions
$XmlWriter.WriteStartElement('Login_Permissions')
$XmlWriter.WriteElementString('Instance', $svr.name)
$XmlWriter.WriteElementString('DBName', $dbase.name)
$XmlWriter.WriteElementString('LoginName', $SQLLogin.name)
foreach($perm in $Dbase.EnumObjectPermissions($u.Name))
{
$XmlWriter.WriteElementString('Permissions', $perm.permissionstate.tostring() + " " + $perm.permissiontype.tostring() + " on " + $perm.objectname.tostring() + " in " + $DBase.name.tostring())
}
$XmlWriter.WriteEndElement() #Login_Permissions
$XMLWriter.WriteEndElement() #Login
} # Next user in database
}
#else
#Skip to next database.
}
}
#Main portion of script start
[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | out-null #ensure we have SQL SMO available
foreach ($SQLsvr in get-content $InputFile) # read the instance source file to get instance names
{
$svr = new-object ("Microsoft.SqlServer.Management.Smo.Server") $SQLsvr
#Cycle through each instance and write the instance information to the file
#Output file is base folder for each of the text files (which will be named for the instance)
$OutputFile = $svr.name
$OutputFile = $OutputFolder+$OutputFile.Replace("\", "-")+".xml"
# get an XMLTextWriter to create the XML
$XmlWriter = New-Object System.XMl.XmlTextWriter($OutputFile,$Null)
# choose a pretty formatting:
$xmlWriter.Formatting = 'Indented'
$xmlWriter.Indentation = "4"
# write the header
$xmlWriter.WriteStartDocument()
# set XSL statements
$XLSPropText="type='text/xsl' href='style.xsl'"
$xmlWriter.WriteProcessingInstruction("xml-stylesheet", $XSLPropText)
# create root element "instances" and add some attributes to it
$xmlWriter.WriteStartElement("Root")
$XmlWriter.WriteStartElement("Instance")
$XmlWriter.WriteElementString("SQLInstance", $svr.name)
$XmlWriter.WriteElementString("SQLVersion", $svr.VersionString)
$XmlWriter.WriteElementString("Edition", $svr.Edition)
$XmlWriter.WriteElementString("LoginMode", $svr.loginmode)
$XmlWriter.WriteEndElement #instance
$SQLLogins = $svr.logins
foreach ($SQLLogin in $SQLLogins)
{
#Iterate through each login, writing the details into the login details
#$XmlWriter.WriteComment("Login Details")
$xmlWriter.WriteStartElement("Logins")
$XmlWriter.WriteElementString("InstanceName", $svr.Name)
$XmlWriter.WriteElementString("LoginName", $SQLLogin.Name)
$XmlWriter.WriteElementString("LoginType", $SQLLogin.LoginType)
$XmlWriter.WriteElementString("Created", $SQLLogin.CreateDate)
$XmlWriter.WriteElementString("DefaultDatabase", $SQLLogin.DefaultDatabase)
$XmlWriter.WriteElementString("Disabled", $SQLLogin.IsDisabled)
$SQLRoles = $SQLLogin.ListMembers()
If ($SQLRoles)
{ $XmlWriter.WriteElementString("ServerRole", $SQLRoles) }
else
{ $XmlWriter.WriteElementString("ServerRole", "Public") }
If ( $SQLLogin.LoginType -eq "WindowsGroup" )
{ #get individuals in any Windows domain groups
$XmlWriter.WriteStartElement("WindowsLogins")
$XmlWriter.WriteElementString("InstanceName", $svr.name)
$XmlWriter.WriteElementString("Login", $SQLLogin.name)
try {
$ADGRoupMembers = get-adgroupmember $SQLLogin.name.Split("\")[1] -Recursive
foreach($member in $ADGRoupMembers)
{ $XmlWriter.WriteElementString("Account", $member.name.tostring() + "(" + $member.SamAccountName.tostring() +")") }
}
catch
{
#Sometimes there are 'ghost' groups left behind that are no longer in the domain, this highlights those still in SQL
$XmlWriter.WriteElementString("Account", "Unable to locate group " + $SQLLogin.name.Split("\")[1] + " in the AD Domain")
}
$XmlWriter.WriteEndElement()
}
#Check the permissions in the DBs the Login is linked to.
If ($SQLLogin.EnumDatabaseMappings())
{
$XmlWriter.WriteStartElement('Permissions')
$XmlWriter.WriteElementString('InstanceName', $svr.name)
$xmlwriter.WriteElementString('Login', $SQLLogin.name)
foreach ( $DB in $svr.Databases)
{
try {
GetDBUserInfo($DB)
}
catch
{
echo $_.Exception|format-list -force
}
} # Next Database
$XmlWriter.WriteEndElement()
}
Else
{
$XmlWriter.WriteStartElement('Permissions')
$XmlWriter.WriteElementString('InstanceName', $svr.name)
$xmlwriter.WriteElementString('Login', $SQLLogin.name)
$XmlWriter.WriteElementString('Permissions', 'No Permissions')
$XmlWriter.WriteEndElement()
}
$xmlWriter.WriteEndElement() #End Logins element
}
}
# close the "machines" node:
$xmlWriter.WriteEndElement() #root node
# finalize the document:
$xmlWriter.WriteEndDocument()
$xmlWriter.Flush()
$xmlWriter.Close()
When running, error message is:
OverloadDefinitions
--------------------
void WriteEndElement()
void WriteEndElement()
No other error or message is given. The file does get written but is incomplete.
when user select the file then in server side file extension will be removed or rename and uploaded it to the server using php codeigniter library
This should remove your file extension
<?php
$var = "testfile.php";
$explode = explode( '.', $var );
array_pop( $explode);
$var = implode( '.', $explode );
var_dump( $var );
As for uploading you will need to read the manual on file uploading
http://www.codeigniter.com/user_guide/libraries/file_uploading.html
file name can be changed using the following codes:
$your_given_name = time().rand().$_FILES["userfiles"]['name'];
$config['file_name'] = $your_given_name;
for changing extension you can use:
if ($this->upload->do_upload('file_name')) {
$file_data=$this->upload->data();
$new_name_by_you='anything'.$file_data['file_ext'];
$new_path=$file_data['file_path'].$new_name_by_you;
rename($file_data['full_path'], $new_path);
}
rename() is a php built in function. for details please visit http://php.net/manual/en/function.rename.php
I recently just had the same issue, and found it really annoying that even when you specified a file_name in code igniter it would append the file extension. Which i did not want.
Blinkydamo's link is not helpfull, since that is the link i was following in the first place and makes no mention of this dilema, although it does demontrate that it is not possible idrectly through Code Igniter - by ommission of the answer.
I haven't tried md asif rahman's method, but it looks sound.
Alternatively you can just forget about using Code Igniter's upload function, and fall back onto PHPs standard one, which is what I have done :
move_uploaded_file($_FILES['imageFile']['tmp_name'], '/path/'.$filename);
where $filename is the exact name of the file including extension, therefore if none is specified - it wont have one.
it is so easy
change code in
libraries/Upload.php
public function set_filename($path, $filename)
{
if ($this->encrypt_name === TRUE)
{
$filename = md5(uniqid(mt_rand()));
}
if ($this->overwrite === TRUE OR ! file_exists($path.$filename))
{
return $filename;
}
$filename = str_replace($this->file_ext, '', $filename);
$new_filename = '';
for ($i = 1; $i < $this->max_filename_increment; $i++)
{
if ( ! file_exists($path.$filename.$i))
{
$new_filename = $filename.$i;
break;
}
}
if ($new_filename === '')
{
$this->set_error('upload_bad_filename', 'debug');
return FALSE;
}
else
{
return $new_filename;
}
}
I am trying to get all files w/in a directory that have the extension ".rtf". I have a working script, but it takes a while, as there is a foreach loop w/in a foreach loop. Is there a faster way to handle this? The goal of the script is to get all files w/in a directory ending in .rtf and use MSWord to Open the file and save it as a ".DOC". The conversion functionality works fine. The issue is with the length of time to search through all of the folders.
Function Convert-Dir($path)
{
$subFolders = get-childitem $path -Recurse | Where-Object {$_.PSIsContainer -eq $True}
if($subFolders)
{
foreach($folder in $subFolders)
{
if($folder.PSisContainer)
{
$Files=Get-ChildItem $folder.fullname -Filter "*.rtf"
$Word=New-Object -ComObject WORD.APPLICATION
if($Files)
{
foreach ($File in $Files)
{
$Doc=$Word.Documents.Open($File.fullname)
$Name=($Doc.name).replace("rtf","doc")
if (Test-Path $Name)
{
} else
{
# Use WORD
$fullName = ($Doc.path + "\" + "Converted_" + $Name)
$Doc.saveas([ref] $fullName, [ref] 0)
$Doc.close()
$fileToRemove = $File.fullName
Remove-Item $fileToRemove
$Word.Quit()
}
}
}
}
}
}
}
I guess the performance is lost by creating a lot of word-instances by calling a word-process in each subfolder. You should should use only one instance of word all the time. Just move the line $Word=New-Object -ComObject WORD.APPLICATION to the top of your function and the line $word.quit() to the very end.
I found a script that does great. The only change I want to make is to list just the files, not the new folders. This script should monitor a folder and subfolders and notify only when a new file has been created. How can I filter this down to just the file? Can I add an exclude on the get-childitem?
Param (
[string]$Path = "\\path\share",
[string]$SMTPServer = "smtp server",
[string]$From = "email",
[string]$To = "email",
[string]$Subject = "New File(s) Received on the FTP site"
)
$SMTPMessage = #{
To = $To
From = $From
Subject = "$Subject at $Path"
Smtpserver = $SMTPServer
}
$File = Get-ChildItem $Path | Where { $_.LastWriteTime -ge (Get-Date).Addminutes(-10) }
If ($File)
{ $SMTPBody = "`nTo view these new files, click the link(s) below:`n`n "
$File | ForEach { $SMTPBody += "$($_.FullName)`n" }
Send-MailMessage #SMTPMessage -Body $SMTPBody
}
Thanks
To list only files, you can pass the -File parameter to Get-ChildItem.
From Get-ChildItem for FileSystem:
To get only files, use the File parameter and omit the Directory parameter.