I need a script which can delete all files which are older than a day and this script needs to be invoked every day automatically in the Sharepoint server.
How can i do this and any hints as how to write the script?
I think an easier way to do it would be to create a site collection policy with an expiration. Set the retention period for one day. You can then attach the disposition workflow to your list which acn be used to clean these files up. You should be able to do all of this without writing any code.
Here is a link with more information about disposition workflow.
http://office.microsoft.com/en-us/sharepointserver/HA101544291033.aspx
Thanks,
Corey
If you really need a script rather than writing code (such as a timer job) then use Powershell to access the SharePoint .NET objects with a scripting engine. Once you've written the script, set up a Windows scheduled task to run it every day.
In the script follow Lars' guidance on using one of those two query classes. Then from the query results you can obtain a reference to each SPListItem you'd like to delete. Either use SPListItem.Delete or SPListItem.Recycle to remove the item.
Here's an example that uses SPQuery:
[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c")
$site = new-object Microsoft.SharePoint.SPSite("http://yoursite/")
$web = $site.OpenWeb("Web Title")
$documentLibrary = $web.Lists["Document Library Name"]
$yesterdaysDate = [Microsoft.SharePoint.Utilities.SPUtility]::CreateISO8601DateTimeFromSystemDateTime([System.DateTime]::UtcNow.AddDays(-1.0))
$query = new-object Microsoft.SharePoint.SPQuery
$query.ViewFields = "<FieldRef Name='Modified' />"
$query.Query = "<Where><Leq><FieldRef Name='Modified' /><Value Type='DateTime' IncludeTimeValue='TRUE'>" + $yesterdaysDate + "</Value></Leq></Where>"
$queryItems = $documentLibrary.GetItems($query)
foreach ($item in $queryItems)
{
echo $item.Url
$item.Delete()
}
$web.Dispose()
$site.Dispose()
You could create a custom timer job in SharePoint using .NET and the WSS API to do the job. Use the SPQuery class to query files by date in a document library. Use the SPSiteDataQuery class if you need to query across multiple document libraries.
Here is C# code to delete only files on SharePoint site which are older than a day, to run this every day you need to create SharePoint Timer Job and add below code inside execute method of timer job.
SPSite spSite = new SPSite("http://YourSiteUrl");
SPWeb oWebsite = spSite.OpenWeb();
SPListCollection collLists = oWebsite.Lists;
foreach (SPList oList in collLists)
{
if (oList.BaseType == SPBaseType.DocumentLibrary)
{
SPDocumentLibrary oDocumentLibrary = (SPDocumentLibrary)oList;
if (!oDocumentLibrary.IsCatalog && oList.BaseTemplate != SPListTemplateType.XMLForm)
{
SPListItemCollection collListItems = oDocumentLibrary.Items;
foreach (SPListItem oListItem in collListItems)
{
if (oListItem.File != null)
{
if ((DateTime.Now - oListItem.File.TimeCreated).TotalDays > 1)
{
oListItem.Delet();
}
}
}
}
}
}
Related
I have a need that for a given sharepoint site, which i have read access to, i need to find out all the list/count of subdirectories & files. The folders go down 3-4 levels.
I have gone through this website for some options -
https://www.softvative.com/blog/2015/02/four-ways-to-get-report-of-sharepoint-folders-and-files-for-a-library/
Still not able to get a list, can anyone suggest a simple way to get that.
Thanks.
The following C# code for your reference.
using (SPSite site = new SPSite("http://sp2013/sites/team"))
{
using (SPWeb web = site.OpenWeb())
{
SPListCollection docLibraryColl = web.GetListsOfType(SPBaseType.DocumentLibrary);
foreach (SPList list in docLibraryColl)
{
Console.WriteLine("-------------LibraryName:" + list.Title + "--------------");
//get all folders in the library
SPListItemCollection oFolders = list.Folders;
//get all files in the library
SPQuery query = new SPQuery();
query.ViewAttributes = "Scope=\"Recursive\"";
var files=list.GetItems(query);
Console.WriteLine("Folder Count:"+oFolders.Count+" | File Count:"+files.Count);
}
}
}
Where can I find a log of login attempts to share point 2007?
Thanks.
PS: I have another question too, I 'd be really grateful if anybody helps me on it:
Sharepoint users are logged out
I haven't been able to find much without a third party tool. Our group is looking into acquiring DocAve by AvePoint.
In the mean time you can at least get an idea in your site analytics area of your site settings dashboard to see how many people have encountered the /_layouts/accessdenied.aspx page. It wont tell you much, but perhaps you can find a way to customize and add a snippet of code that will take a user's ID when they hit that page. Its not perfect, so I'd suggest a 3rd party tool unless you can scan all of your web front ends etc.
We had a similar requirement once, where we needed to log the last visited time of all the users on the site. So after some period of time, say 90 days, if a particular user had not logged into the site, the admin could delete his profile.
We overcame this problem with a very simple approach. You can follow the sample code for your reference.
You would need to create a list in your site by the name "UserLoginDetails" and create a column "LastLogIn" in that. Code is self explanatory.
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Xml.Serialization;
using Microsoft.SharePoint;
namespace Ubaid.WebParts
{
[Guid("883a77d6-271d-4b88-9ca2-d5150a00520b")]
[DefaultProperty("Text"), ToolboxData("<{0}:UserLastVisited runat=server></{0}:UserLastVisited>"), XmlRoot(Namespace = "Ubaid.WebParts")]
public class UserLastVisited : System.Web.UI.WebControls.WebParts.WebPart
{
protected override void CreateChildControls()
{
base.CreateChildControls();
string siteName = SPContext.Current.Web.Url;
using (SPSite site = new SPSite(siteName))
{
SPWeb web = site.OpenWeb();
site.AllowUnsafeUpdates = true;
web.AllowUnsafeUpdates = true;
SPList UserLoginDetailsList = web.Lists["UserLoginDetails"];
SPQuery query = new SPQuery();
string uname = SPContext.Current.Web.CurrentUser.LoginName;
query.Query = "<Where><Eq><FieldRef Name='Title'/><Value Type='Text'>" + uname + "</Value></Eq></Where>";
SPListItemCollection listItemColl = UserLoginDetailsList.GetItems(query);
if (listItemColl.Count > 0)
{
SPListItem item = listItemColl[0];
item["LastLogIn"] = DateTime.Now.ToLocalTime();
item.Update();
}
else
{
SPListItem item = UserLoginDetailsList.Items.Add();
item["Title"] = uname;
item["LastLogIn"] = DateTime.Now.ToLocalTime();
item.Update();
}
}
}
}
}
You can insert this webpart in your masterpage, as the data in this list needs to be updated on every page load.
Not sure which is the best way to do it / performance issues, but since ours was a small site we could manage with this pretty well.
I'm surprised that I cannot find on the net a solution where I could manage views for content types. Do I really have to visit each task list with my browser to add/modify a view?
Is there any solutions available that would allow me to just define a view for content type and thus make this view available on all lists where content type is?
Directly speaking, no, a view cannot be assigned to a content type. Lists are what hold an actual view collection, and the corresponding aspx page that is created with it. A view also has a dependent existence with its list: you cannot have a view that is not associated with a list. There is also no "event handler" for adding a content type to a list, either, so you can't have some automatic process that occurs whenever you add a content type to the list (and it would be cumbersome anyway as you'd have to attach the event handler to the list in the first place!).
This isn't to say you have to manually muck about in the UI to accomplish the task, though. Using the object model in something like a custom code workflow, you can sweep across your entire SPWeb and create a new view on each list that has the specified content type. All you need is a workflow with a single code activity, which iterates across all of the SPLists in SPWeb.Lists, and check if that SPList has the content type with the same name as your target content type. If it does, create a new SPView with the parameters you need. Since you cannot simply create one SPView and clone it, as an SPView must be associated with a list and cloning an SPView just clones it onto the same list, you'll have to run the whole SPView creation in each loop. But you only have to write it once, it's the system that'll have to run it multiple times. And by heavens, it'll certainly get that done a lot more productively than if you had to dance about in the UI for a few hours.
Simply run the workflow any time you need to reassert the existence of that SPView.
I found this solution in c#, however I have not yet tested it.
I will test it in the future, and update this if necessary.
Apparently, it is for SharePoint 2010, however it may work in later versions too.
private void CreateView(string strViewName)
{
try
{
string fieldName = //Get Field Internal Name
var docquery = "<Where><Eq><FieldRef Name='" + fieldName.ToString() + "' /><Value Type='Choice'>" + strViewName.ToString() + "</Value></Eq></Where>";
System.Collections.Specialized.StringCollection viewFields = new System.Collections.Specialized.StringCollection();
viewFields.Add("Type");
viewFields.Add("Name");
viewFields.Add("Modified");
viewFields.Add("Modified By");
viewFields.Add(fieldName.ToString());
oViewCollection.Add(strViewName, viewFields, docquery, 100, true, false);
web.Update();
}
catch (Exception e)
{
throw new SPException(e.Message.ToString());
}
}
I also found this solution in PowerShell...
Add-PSSnapin Microsoft.SharePoint.PowerShell -EA silentlycontinue
#Title View
$viewTitle = "Sort by modified date"
#Add the column names from the ViewField property to a string collection
$viewFields = New-Object System.Collections.Specialized.StringCollection
$viewFields.Add("DocIcon") > $null
$viewFields.Add("LinkFilename") > $null
$viewFields.Add("Modified") > $null
$viewFields.Add("Editor") > $null
$viewFields.Add("FileSizeDisplay") > $null
#Query property
$viewQuery = "<OrderBy><FieldRef Name='Modified' Ascending='FALSE'/></OrderBy>"
#RowLimit property
$viewRowLimit = 50
#Paged property
$viewPaged = $true
#DefaultView property
$viewDefaultView = $false
$ListsToUpdate = #()
$App = Get-SPWebApplication http://....
foreach ($Site in $App.Sites)
{
foreach ($Web in $Site.AllWebs)
{
foreach ($List in $Web.Lists)
{
if($List.BaseType -eq "DocumentLibrary" -and $List.Title -eq "Documents" )
{
$ListsToUpdate += $Web.Lists[$List.Title]
}
}
}
}
foreach($List in $ListsToUpdate)
{
Write-Host $List.Title
#Create the view in the destination list
$newview = $List.Views.Add($viewTitle, $viewFields, $viewQuery, $viewRowLimit, $viewPaged, $viewDefaultView)
}
I need to check for duplicates. Currently I have items stored in sub folders in a list.
How can I retrieve all items in the list from a web service, so I can check for duplicates?
Here is code from object model: I want to do exactly this, but from a web service
private static void PrintItemTitles()
{
string strUrl = "http://localhost:8099/";
using (SPSite site = new SPSite(strUrl))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists["MyList"];
SPListItemCollection items = list.Items;
foreach (SPListItem item in items)
if (item != null)
Console.WriteLine(item.Title);
}
}
}
Use SPList.Items doesn't return all items? Well, then try SPList.GetItems(SPQuery).
Have a following SPQuery:
SPQuery query = new SPQuery();
query.ViewFields = "<FieldRef Name='ID'/><FieldRef Name='Title'/>";
query.Query = String.Format("<Where><Eq><FieldRef Name='Title'/><Value Type='Text'>{0}</Value></Eq></Where>", someItemTitle)
query.MeetingInstanceId = -1; //In case if you query recurring meeting workspace - get items from all meetings
query.RowLimit = 10; //Will you have more than 10 duplicates? Increase this value
query.ViewAttributes = "Scope='RecursiveAll'"; //Also return items from folders subfolders
Note: There could be some mistakes in code, because i`m writing from top of my head
By executing this query and if it returns more than one item, then you have a duplicate!
Edit: Ahh, sorry, you are talking about Web Services.
Then this code won't help. There are 2 options then:
Option 1: You CAN create a view that
does include items even from folders
(flat view). See here for
instructions.
Option 2: According to Lists Web Service's GetListItems method, you can pass QueryOptions parameter. Pass in
<QueryOptions>
<MeetingInstanceID>-1</MeetingInstanceID> <!-- Again, if you query recurring meeting, you want ALL items -->
<ViewAttributes Scope='RecursiveAll' /> <!-- or Recursive if that does not work -->
</QueryOptions>
Good luck!
You can use the Lists.asmx web service, but that is quite hard to do as it returns quite a lot of information. I would deploy a custom web service on my SharePoint environment that contains that code and returns the list items.
Edit: This is a decade old so very likely not to be relevant to anyone, if google has brought you here I would be sceptical of the content against more modern frameworks!
We have a sharepoint website that has been quite heavily developed with content using the out of the box content editor webpart. This is a bit rubbish when it comes to using any other browser than IE.
We have in mind to update to the free Telerik content editor, however we would like to save ourselves a large amount of copy and pasting, and clicking and selecting to swap the web parts over.
There seems to be no official upgrade path but it seems to me that it must be possible to use the power of code (tm) to grab the content of the original webpart, new up a telerik webopart and put the content into the new webpart... then delete the old original web part.
Has anyone done this sort of thing? How is it best to lay out the code and actually run the code that will do the swap (if it is possible). A fresh webpart with a "Do Swap" button on? or something more sophisticated?
I also would need to walk through every page and subsite (and page in subsite) and look at every web part. Is there a best practice way of doing this?
I would write a console application for this.
Open the root Web and iterate through its sub webs.
Do the work needed for each page, by opening the WebPartManager.
Here are some pseudo code to get you started.
string SourceUrl = "http://ThisWeb";
using (SPSite sourceSite = new SPSite(SourceURL))
{
using (SPWeb sourceWeb = sourceSite.OpenWeb(SourceURL))
{
IterateSubWebsProd(sourceWeb):
}
}
private void IterateSubWebsProd(SPWeb sourceWeb)
{
// This is the migration function
DoThingyWithThisWeb(sourceWeb);
foreach (SPWeb subWeb in sourceWeb.Webs)
{
IterateSubWebsProd(subWeb);
subWeb.Dispose();
}
}
private void DoThingyWithThisWeb(SPWeb sourceWeb)
{
PublishingPage currentPage = null;
string currentPageName = "<something>";
// Find the pages that you want to modify, with a CAML query for example
SPQuery query = new SPQuery();
query.Query = string.Format("" +
"<Where>" +
"<Eq>" +
"<FieldRef Name='FileLeafRef' />" +
"<Value Type='File'>{0}</Value>" +
"</Eq>" +
"</Where>" +
"", currentPageName);
// This codesnippet is from a Publishing web example
PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(sourceWeb);
PublishingPageCollection pageColl = publishingWeb.GetPublishingPages(query);
if (pageColl.Count > 0)
{
currentPage = pageColl[0];
}
using (SPLimitedWebPartManager wpMan = currentPage.ListItem.File.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared))
{
foreach (WebPart wp in wpMan.WebParts)
{
if (wp.GetType().Equals(typeof(Microsoft.SharePoint.WebPartPages.ContentEditorWebPart)))
{
Microsoft.SharePoint.WebPartPages.ContentEditorWebPart thisWebPart = wp as Microsoft.SharePoint.WebPartPages.ContentEditorWebPart;
// This is just dummy code, here you will do your content migration
XmlDocument xmlDoc = new XmlDocument();
XmlElement xmlElement = xmlDoc.CreateElement("RootElement");
xmlElement.InnerText = sourceItem[SourceField].ToString();
thisWebPart.Content = xmlElement;
wpMan.SaveChanges(thisWebPart);
}
}
}
}
I'm not 100% certain on this, but if your content is saved into a list as individual fields, could you not point the Telerik controls at where that content is saved? This may cause Telerik controls to freak out a bit on the first edit of that content, but they should be ok to re-format the content and recover.